为什么翻转 1 时不会给出意想不到的结果?

Jam*_*iff 0 c++ bitwise-operators bitwise-not

我目前正在学习按位运算符的过程,我遇到了一些我不太明白的事情。

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

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

然而,当运行这个时,我得到的结果是-2。谁能解释一下为什么这不起作用?

ant*_*duh 6

您正在使用有符号整数。如果您使用无符号整数(并且该整数只有 4 位,但事实并非如此),则会出现预期结果 (14)。

相反,对于有符号整数,具有最高位集的所有值都是负值 - 这就是补码的工作原理。例如,如果有 16 位,则0b0000_0000_0000_0000through 的值0b0111_1111_1111_1111将分配给正值(“0”到“32767”),同时0b1000_0000_0000_0000through 的值0b1111_1111_1111_1111将分配给负值(“-32768”到“-1”)。

而且,int通常大于4位;它通常是 32 位的。1 的否定将是0b1111_1111_1111_1111_1111_1111_1111_1110, not 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 );
}
Run Code Online (Sandbox Code Playgroud)

  • “嗨,我已经尝试过 uint16_t(无符号 16 位) x uint16_t x = 1; x = ~x,结果是它可以容纳的最大值 -1 (65534)” 好的;*你对这个结果感到困惑吗?如果是这样,*为什么*?您*相反*期望什么?为什么? (2认同)