如何用按位运算替换这个if / else语句?

时间:2012-03-23 10:39:39

标签: c++ bit-manipulation

我在做按位&在两个位数组之间保存old_array中的结果,我想摆脱if / else语句。我应该使用BIT_STATE宏,但是怎么做?

#define BYTE_POS(pos) (pos / CHAR_BIT)
#define BIT_POS(pos) (1 << (CHAR_BIT - 1 - (pos % CHAR_BIT)))
#define BIT_STATE(pos, state) (state << (CHAR_BIT - 1 - (pos % CHAR_BIT)))

if (((old_array[BYTE_POS(old_pos)] & BIT_POS(old_pos)) != 0) && 
   ((new_array[BYTE_POS(new_pos)] & BIT_POS(new_pos)) != 0))
{
   old_array[BYTE_POS(old_pos)] |= BIT_POS(old_pos);
}
else
{
      old_array[BYTE_POS(old_pos)] &= ~(BIT_POS(old_pos));
}

3 个答案:

答案 0 :(得分:1)

您始终可以计算两个结果,然后将其合并。最大的问题是计算拟合位掩码。

E.g。

const uint32_t a = 41,
      uint32_t b = 8;

const uint32_t mask[2] = { 0, 0xffffffff };

const uint32_t result = (a&mask[condition])
                      | (b&mask[!condition]);

或避免一元不

const uint32_t mask_a[2] = { 0, 0xffffffff },
               mask_b[2] = { mask_a[1], mask_a[0] };

const uint32_t result = (a&mask_a[condition])
                      | (b&mask_b[condition]);

但是:在进行按位操作时,请务必小心所涉及的位数。一种需要注意的方法是固定大小类型,如uint32_t,可能在您的平台上定义,也可能不定义(但如果不是,那么好的是你得到编译错误),或者小心使用模板。其他类型(包括charint甚至bool可以包含超出某些定义的最小值的任何大小。

答案 1 :(得分:0)

是的,这样的代码看起来有些难看。 我不认为BIT_STATE在这里很有用。 (状态必须为0或1才能按预期工作)

我看到了以下方法来摆脱它们

a)使用C ++位域

例如 http://en.wikipedia.org/wiki/Bit_field

b)中 在类/方法/函数中“隐藏”该代码

c)中 我认为这相当于你的代码

if ((new_array[BYTE_POS(new_pos)] & BIT_POS(new_pos)) == 0))
{
   old_array[BYTE_POS(old_pos)] &= ~(BIT_POS(old_pos));
}

或作为内联

   old_array[BYTE_POS(old_pos)] &= 
      ~((new_array[BYTE_POS(new_pos)] & BIT_POS(new_pos)) ? 0 : BIT_POS(old_pos));

答案 2 :(得分:0)

采用表达式

(new_array [BYTE_POS(new_pos)]&amp; BIT_POS(new_pos))

为0或在BIT_POS(new_pos)位中有1并将其移位到该位,如果设置为BIT_POS(old_pos)

(new_array [BYTE_POS(new_pos)]&amp; BIT_POS(new_pos))&lt;&lt; (old_pos - new_pos)

现在和old_array的结果[BYTE_POS(old_pos)]

old_array [BYTE_POS(old_pos)]&amp; = old_array [BYTE_POS(old_pos)]

唯一的诀窍是它依赖于实现(至少它曾经是)如果你移动负数会发生什么。因此,如果您已经知道old_pos是大于还是小于new_pos,则可以替换&gt;&gt; (new_pos - old_pos)在适当的时候。

我没试过这个。我可能有&lt;&lt;和&gt;&gt;交换。