Puzzle 33: Looper Meets the Wolfman

非零整数和自身的相反数相等

如标题,传说有让下式为true的整数i

i != 0 && i == -i

试试i = 1, 2, 3, ...当然会返回false的,这个……

不过,试试i = Integer.MIN_VALUE或者i = Long.MIN_VALUE,上面那个式子的值就true了。

咄咄怪事!

推一下先,以下都是补码。

Integer.MIN_VALUE = -2^31用二进制表示即为:

1000 0000 0000 0000 0000 0000 0000 0000

按照JSL 15.15.4,For all integer values x, -x equals (~x)+1. 那么,-Integer.MIN_VALUE就是:

0111 1111 1111 1111 1111 1111 1111 1111

+ 1

= 1000 0000 0000 0000 0000 0000 0000 0000

和Integer.MIN_VALUE相等了。

对于Long.MIN_VALUE,有Long.MIN_VALUE == -Long.MIN_VALUE,原因同上。

在用有限位表示整数时,用补码,会使负数的个数比正数多一个,那个绝对值最大的负数如果取相反数,按理,是没有对应的正数来表示的,但Java并不理会这个事实上的溢出,依然套用补码计算方式进行运算,就出现上面的错误。

但对于Short和Byte类型,Java就处理过——cast到较大的数型中以不保正确性,使-Short.MIN_VALUE=32768,-Byte.MIN_VALUE=128。

  1. 相关Puzzle: Puzzle 26
  2. JSL 15.15.4, Unary Minus Operator -
  3. TODO: 书中附带讲了一部分模代数的内容,稍后再看