理解c中的按位补码

understanding bitwise complement in c

我不明白这段代码的输出:

main() {
    int ret = ~(~0 <<5) << 2;
    printf("ret: %d, %u\n", ret, ret);
}


output:
ret: 124, 124

如果我进行心理处理,我会这样做:

我做错了什么?

C 中的整型文字默认为 intint 通常为 4 个字节长(取决于编译器)。这意味着~0不是1,而是32个1。

~0 == 11111111111111111111111111111111
~0 << 5 == 11111111111111111111111111100000
~(~0 << 5) == 00000000000000000000000000011111
~(~0 << 5) << 2 == 00000000000000000000000001111100

resolving ~0 gives binary 1

这是不正确的。

0 由全零位表示。 ~0 将所有位变为 1。在 32 位系统上,

0 == 00000000 00000000 00000000 00000000
~0 == 11111111 11111111 11111111 11111111 

~0 在二进制中全为 1。

左移 5 位将有 5 个 0,然后全为 1。

~这是5个1;这是 31。

左移2位等于乘以4,最后答案是124。

if int is 4 bytes then:
~0        = 11111111111111111111111111111111 = -1        
-1 << 5   = 11111111111111111111111111100000 = -32        
~-32      = 00000000000000000000000000011111 =  31          
31 << 2   = 11111111111111111111111000000000 = 124        

if int is 2 bytes then:
~0        = 1111111111111111                 = 65535
65535 << 5= 1111111111100000                 = 65504
~65504    = 0000000000011111                 = 31
31 << 2   = 0000000001111100                 = 124


int is guaranteed to be able to hold -32767 to 32767,
which requires 16 bits.
In that case, int , is 2 bytes.
However, implementations are free to go beyond that minimum,
as you will see that many modern compilers make int 32-bit 
(which also means 4 bytes pretty ubiquitously).