我对比特操纵相当新,我试图弄清楚(1 <&lt; 31)-1是如何工作的。
首先,我知道1&lt;&lt; 31是
1000000000000000000000000000
我知道它实际上是最小int值的补充,但当我试图找出(1 <&lt; 31)-1时,我发现一个解释说明,它只是< / p>
10000000000000000000000000000000 - 1 = 01111111111111111111111111111111
我几乎想要相信它,因为它非常简单。但这真的发生了什么?如果不是,为什么它恰好是正确的?
我原来的想法是,真正的过程应该是:-1的两个补码是
11111111111111111111111111111111
然后(1 <&lt; 31)-1 =
(1)01111111111111111111111111111111
最左边的1被放弃,然后我们有最大的int值。
我真的很困惑哪一个是对的。
答案 0 :(得分:5)
两者都是! 1&lt;&lt; 31是:
1000 0000 0000 0000 0000 0000 0000 0000
减1给出:
0111 1111 1111 1111 1111 1111 1111 1111
关于有符号数的二进制补码布局的一个很好的特性是加法和减法与无符号数字的操作完全相同。因此10000 ... 000表示二进制补码中的负数,最大负数,在这种情况下为-2,147,483,648,从中减去1导致回绕到最大正数2,147,483,647,但是排列了两个补数这样我们就可以假装它是一个无符号数字,所以减法并不复杂。从10000 ... 000中减去1只会将前导1减少到0,并借用一堆1,与十进制相同,得到一堆9:10000 - 1 = 9999。
在数学上,(a - b)
与(a + (-b))
相同也是如此,因此我们可以改为(1 << 31) + (-1)
:
1000 0000 0000 0000 0000 0000 0000 0000 (1 << 31)
1111 1111 1111 1111 1111 1111 1111 1111 (-1)
-----------------------------------------
1 0111 1111 1111 1111 1111 1111 1111 1111 +
0111 1111 1111 1111 1111 1111 1111 1111 (truncate)
从高端执行1,并在结果被截断为32位整数后丢失。
无论哪种方式,该模式在高端使用单个0,然后填充1s,表示任意宽度的二进制补码整数的最大正值。
如果您愿意,还有其他方法可以生成该模式,例如~(1 << 31)
和(-1 >>> 1)
(其中>>>
表示logical shift right),这与广告的宽度无关整数。