int a = Integer.MIN_VALUE;
int b = -a;
System.out.println("a = "+a + " | b = "+b);
结果:
a = -2147483648 | b = -2147483648
我原本期望b是一个正数。
int a = Integer.MIN_VALUE;
int b = -a;
System.out.println("a = "+a + " | b = "+b);
结果:
a = -2147483648 | b = -2147483648
我原本期望b是一个正数。
改变 Integer.MIN_VALUE
的符号会产生溢出;你看到的就是其结果。
如果您曾经做过类似这样的事情:
int a = Integer.MAX_VALUE;
a++;
System.out.println(a);
当某个值超过数据类型的最大值时,它会循环回到最小值。当它小于最小值时,它会循环回到最大值。
在这里也是同样的情况。
对整数的最小值取反,在数学上会得到2147483648,但是由于那个值比最大值还要大1,所以它又会回到最小值,也就是-2147483648。
有趣的事实:取反基本上是将每个位从0变成1,从1变成0,然后再加一。试试对这个值在二进制下长这样:10000000000000000000000000000000 进行取反操作。
所以,在二进制中最小的负数是1000 0000。要反转符号,需要翻转所有比特位,并加1,如下:
1000 0000 => 0111 1111 + 1 = 1000 0000
这样就回到了起点!
就像上面的例子一样,字节(8位)的有符号范围是-128到127,因此-(-128)为128,即127的倒数,因此它会溢出并返回-128。
至于为什么要使用补码?1 - 1变成了1 +(-1),或者0001 + 1111 = 0000。因此,通过在补码中存储负数,只需取第二个数的补码并将它们相加就可以完成减法(这比向算术逻辑单元(ALU)添加减法电路更有效;因为它已经具有按位非和加法来进行补码操作)。
2147483648 -will become-> -2147483648
2147483649 -will become-> -2147483647
2147483650 -will become-> -2147483646
a
的值为-2147483648
。int b = -a;
时,通常b
应该具有。b = -a --> -(-2147483648) --> 2147483648
2147483647
,而 2147483648
比 2147483647
大 1,它将循环回来并变成 -2147483648
。
b
之前将1添加到a
,则应该可以正常工作。 - AntonHbyte
类型,取值范围为-128到127... 如果您有一个值为-128的字节x
,那么-x
的值将是多少? - Jon Skeetb
是一个正数,那么您期望是多少正数,并且为什么期望如此,鉴于Integer.MAX_VALUE
是2147483647? - Andreas