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。
附
- 相关Puzzle: Puzzle 26
- JSL 15.15.4, Unary Minus Operator -
- TODO: 书中附带讲了一部分模代数的内容,稍后再看