0

我目前正在学习按位运算符的过程,并且遇到了一些我无法弄清楚的事情。

我目前正在使用 NOT(~) 运算符,它应该反转所有位。因此,为了更好地理解它,我尝试创建一个程序来翻转数字 1 的位。

int main()
{
    int x = 1; // 0001 in binary
    int y = ~x; // should flip the bits, so its 1110, or 14
    cout << y; 
}

但是,当运行它时,我得到 -2 结果。谁能解释为什么这不起作用?

4

1 回答 1

6

您正在使用有符号整数。如果您使用无符号整数(如果整数只有 4 位,则不是),您的预期结果 (14) 会出现。

相反,对于有符号整数,所有设置最高位的值都是负值——这就是二元补码的工作原理。例如,如果您有 16 位,则0b0000_0000_0000_0000通过值0b0111_1111_1111_1111分配给正值(“0”到“32767”),同时将值分配给负值(“-32768”到“-1”)0b1000_0000_0000_00000b1111_1111_1111_1111

还有,int通常是4位以上;它通常是 32 位的。1 的否定是0b1111_1111_1111_1111_1111_1111_1111_1110,不是0b1110

0b1111_1111_1111_1111_1111_1111_1111_1110当被视为有符号整数时,-2使用二进制补码规则。

0b1111_1111_1111_1111_1111_1111_1111_1110当被视为无符号整数时4,294,967,294,等于2^32 - 2

#include <stdio.h>
#include <cstdint>

// Program prints the following:
//   unsigned int_8:   254
//   signed   int_8:   -2
//   unsigned int_16   65534
//   signed   int_16   -2
//   unsigned int_32   4294967294
//   signed   int_32   -2

int main() {
    printf( "unsigned int_8:   %hhu\n", (uint8_t)~1 );
    printf( "signed   int_8:   %d\n", (int8_t)~1 );

    printf( "unsigned int_16   %hu\n", (uint16_t)~1 );
    printf( "signed   int_16   %d\n", (int16_t)~1 );

    printf( "unsigned int_32   %u\n", (uint32_t)~1 );
    printf( "signed   int_32   %d\n", (int32_t)~1 );
}
于 2022-02-14T19:52:10.243 回答