我在做按位&在两个位数组之间保存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));
}
答案 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,可能在您的平台上定义,也可能不定义(但如果不是,那么好的是你得到编译错误),或者小心使用模板。其他类型(包括char
,int
甚至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;交换。