两者都是! 1
1000 0000 0000 0000 0000 0000 0000 0000
减去 1 得出:
0111 1111 1111 1111 1111 1111 1111 1111
有符号数的二进制补码布局的一个很好的功能是,加法和减法与它们的运算完全相同unsigned数字。因此 10000...000 表示二进制补码中的负数,即最大负数,在本例中为 -2,147,483,648,从中减去 1 会导致回绕到最大正数 2,147,483,647,但二进制补码数已排列这样我们就可以假装它是一个unsigned而是数字,因此减法并不复杂。从 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 位整数,该 1 就会丢失。
无论哪种方式,该模式(在高端有一个 0,然后用 1 填充)是任意宽度的二进制补码整数的最大正值的表示。
如果您愿意,还有其他方法可以生成该模式,例如~(1 << 31)
, and (-1 >>> 1)
(where >>>
means 逻辑右移 https://en.wikipedia.org/wiki/Logical_shift) 与整数的宽度无关。