如何用逐位操作替换此if/else语句

How to replace this if/else statement with bitwise operations?

本文关键字:else 语句 if 何用逐 位操作 替换      更新时间:2023-10-16

我正在做逐位&在两个位数组之间,将结果保存在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));
}

您总是可以计算两个结果,然后将其组合。最大的问题是计算一个合适的位掩码。

例如

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,可以具有超出某个定义的最小值的任何大小。

是的,这样的代码看起来有些难看。我认为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));

取表达式

(new_array[BYTE_POS(new_POS)]&BIT_POS(new_POS))

其在比特bit_POS(new_POS)中为0或具有1,并将其移位直到该比特(如果设置在比特_POS(old_POS)中)

(new_array[BYTE_POS(new_POS)]&BIT_POS(new_POS))<lt;(旧操作系统-新操作系统)

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

old_array[BYTE_POS(old_POS)]&=old_array[BYTE_POS(old_POS)]

唯一的诀窍是,它取决于实现(至少过去是这样),如果偏移了负数,会发生什么。因此,如果您已经知道old_pos是大于还是小于new_pos,则可以在适当的时候替换>>(new_pos-old_pos)。

我还没试过。我可能有<lt;和>>交换。