65.9K
CodeProject 正在变化。 阅读更多。
Home

更简单的位运算

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.46/5 (10投票s)

2001年12月21日

CPOL

2分钟阅读

viewsIcon

152335

downloadIcon

780

一组简化位运算理解的模板。

引言

我使用 C/C++ 开发软件已经很长时间了,但我仍然需要三思而后行,当我遇到位运算时,更不用说当我必须向其他人解释它们时了!例如

    unsigned const STAT_ONE = 0x0001;
    unsigned const STAT_TWO = 0x0002;
    
    unsigned status = 0x0001;
    if(status & (STAT_ONE | STAT_TWO)) // Does this evaluate to true or false?
       DoSomething();

我们都知道前面的语句检查是否同时设置了 STAT_ONESTAT_TWO 位,然后将执行 DoSomething()... 还是设置了 STAT_ONESTAT_TWO 位? 让我们看看

    0001 or   // STAT_ONE
    0010      // STAT_TWO
    ----
    0011 and  // STAT_ONE | STAT_TWO
    0001      // status
    ----
    0001      // status & (STAT_ONE | STAT_TWO)

因为结果为非零,所以将执行 DoSomething()。我认为这可能非常棘手,特别是如果表达式变得太复杂。下面的代码的意图是否更容易理解,并且不易出错?

    unsigned const STAT_ONE = 0x0001;
    unsigned const STAT_TWO = 0x0002;

    unsigned status = 0x0001;
    if(isAnyBitSet(status, STAT_ONE | STAT_TWO)) // This evaluates to true, bit
                                                 // STAT_ONE is set and bit STAT_TWO 
                                                 // isn't. Same as previous example
       DoSomething();
    if(areAllBitsSet(status, STAT_ONE | STAT_TWO)) // This evaluates to false, 
                                                   // bit STAT_ONE is set but bit 
                                                   // STAT_TWO isn't
       DoSomething();

而且通过其位置访问位的数值也很方便,就像这样

    if(isBitSetByPos(status, 5))   
       bitClearByPos(status, 5);

BitTools.h 头文件中提供的所有函数都是内联的,因此无需担心大小或运行时速度的权衡。

模板

基于位掩码的函数

  • template <class T, class U>
    	bool isAnyBitSet(T value, U mask)

    如果 mask 中的任何位在 value 中被设置,则返回 true。 定义为:(value & mask) != 0

       1010 and  // value
       0110      // mask
       ----
       0010      // Non-zero: true
  • template <class T, class U>
    	bool areAllBitsSet(T value, U mask)

    如果 mask 中的所有位都在 value 中被设置,则返回 true。 定义为:(value & mask) == mask

       1010 and  // value
       1110      // mask
       ----
       1010      // 1010 == 1010: true
  • template <class T, class U>

    bool areAllBitsClear(T value, U mask)

  • 如果 mask 中的所有位在 value 中被清除,则返回 true。 定义为:(value & mask) == 0
       1010 and  // value
       0101      // mask
       ----
       0000      // Zero: true
  • template <class T, class U>
    	T setBits(T value, U mask)

    mask 位设置为 value 并返回 value。 定义为:value | mask

       1000 or   // value
       0110      // mask
       ----
       1110
  • template <class T, class U>
    	T setBitsExcept(T value, U mask)

    返回 value,其中所有位都被设置,除了 mask 位。 定义为:value | ~mask

       1001 not  // mask
       ----
       0110 or   // ~mask
       0001      // value
       ----
       0111
  • template <class T, class U>
    	T clearBits(T value, U mask)

    清除 mask 位并返回 value。 定义为:value & ~mask

       1001 not  // mask
       ----
       0110 and  // ~mask
       1111      // value
       ----
       0110
  • template <class T, class U>
    	T clearBitsExcept(T value, U mask)

    返回 value,其中所有位都被清除,除了 mask 位。 定义为:value & mask

       0010 and  // value
       0110      // mask
       ----
       0010
  • template <class T, class U>
    	T setClearBits(T value, U add, U remove)

    返回 value,其中设置 add 位并清除 remove 位。 定义为:(value | add) & ~remove

       1101 or   // value
       0101      // add
       ----
       0111
    
       0001 not  // remove
       ---- 
       1110 and  // ~remove
       0111      // value | add
       ----
       0110
  • template <class T, class U, class V>
    	T setBits(T value, U mask, V set)

    根据 set 的值,返回 value,其中设置或清除了 mask 位。

基于位置的函数

  •  

    template <class T>
    	T setBitByPos(T value, unsigned char n)

    将第 n 位设置为 value 并返回 value。 定义为 value | (1 << n)

  •  

    template <class T>
    	T clearBitByPos(T value, unsigned char n)

    清除第 n 位并返回 value。 定义为 value & ~(1 << n)

  •  

    template <class T>
    	bool isBitSetByPos(T value, unsigned char n)

    如果 value 具有设置的第 nth 位,则返回 true。 定义为 (value & (1 << n)) != 0

  •  

    template <class T>
    	bool isBitClearByPos(T value, unsigned char n)

    如果 value 具有清除的第 nth 位,则返回 true。 定义为 (value & (1 << n)) == 0

结论

BitTools.h 中包含的模板提供了一种更容易、更不易出错的方式来表达位运算,与手写代码相比,没有性能或大小的损失。 我希望您发现这些函数像我一样有用且易于使用。

© . All rights reserved.