为什么C ++按位AND运算符在不同大小的操作数下会表现出这样的行为?

时间:2018-10-30 15:30:02

标签: c++ bit-manipulation

对使用大小写operator ~删除位时类型大小是否是一个因素感到好奇,我最终得到了这个奇怪的结果:

uint64_t x = 0xccccccccccccccccUL;
uint8_t y = 10;
auto z = ~y; // Debugger calls z an 'int' with value of 0xfffffff5
x &= z;
// x is now the correct value: 0xccccccccccccccc4

operator &如何返回大于两个操作数之一的值?

以下示例进一步使我感到困惑,因为看起来逻辑相同,但产生的结果却不同:

uint64_t x = 0xccccccccccccccccUL;
x &= 0xfffffff5;
// Now x is 0x00000000ccccccc4

这解释了什么?不管类型大小/符号如何,实际上都可以使用x &= ~y删除位吗?

1 个答案:

答案 0 :(得分:3)

您要在此处进行两次扩展操作。第一个是您的 TypeError: undefined is not an object (evaluating 'item.receiver.first_name') ,它(像任何算术运算符一样)执行标准的“整数提升”。在这种情况下,由于源类型(~)的所有值都可以放入uint8_t中,因此执行了升级。因此,您已经注意到,int被推导为类型z

第二个扩展操作是int,在这种情况下,它等效于&=x = x & z不适合uint64_tint,甚至不适合unsigned int,但int64_tuint64_t都适合int中,因此就是所选类型。扩展(有符号的)uint64_t涉及符号扩展,因此这就是多余位的来源。

要回答您的最后一个问题,,如果int具有符号类型或比{{1窄},使用x &= ~y来清除一点是不安全的}}。有关更多信息,请参见this article,但最重要的是,如果可能会扩大促销范围,请确保将y转换为预期的 unsigned 类型。如果您使用x而不是~var来使用uint8_t,则不会遇到此问题。