(给ImportNew加星标,提高Java技能)
编译:ImportNew/覃佑桦
programming.guide/java/minus-min-value.html
出人意料的是,下面两个表达式的计算结果居然为 true:
-Integer.MIN_VALUE == Integer.MIN_VALUE // true
-Long.MIN_VALUE == Long.MIN_VALUE // true
而 Byte 和 Short 的结果看起来和预期的一样:
-Byte.MIN_VALUE == Byte.MIN_VALUE // false
-Short.MIN_VALUE == Short.MIN_VALUE // false
这背后究竟发生了什么?
分析
Java 用两个补码表示整数。用这种表示方法,value 在起点不对称。负数的个数比正数少。最小负数没有对应的正数!例如:
Integer.MIN_VALUE 等于 −231
Integer.MAX_VALUE 等于 +231−1
尝试对 −231 取反时,会得到 231 超出最大整数,因此会发生溢出变为负数。
示例:
换句话说,Integer.MIN_VALUE等于对自己取反。这也会引起其它意外情况,例如 Math.abs(Integer.MIN_VALUE),的实现为x < 0 ? -x:x,会回负值。
那么 byte 和 short 会怎么样?
byte 和 short 也是用两个补码存储。但是,Java 不会直接对 byte 和 short 进行算术运算。相反,它们会先被提升为 ints,然后进行取反。
假设 b 是 byte,那么 -b 等价于 –((int) b)。
通过两个重载方法可以很好地进行说明。
void m(byte b) { System.out.println(“A byte”); }
void m(int i) { System.out.println(“An int”); }
按照下面进行调用:
byte b = 0;
m(b); // Prints “A byte”
m(-b); // Prints “An int”
因此,-Byte.MIN_VALUE 等于128,但类型为 int。如果把结果转回 byte(最大值为127),将翻转并变为−128,与 int 和 long 的情况一样:
(byte) -Byte.MIN_VALUE == Byte.MIN_VALUE // true
(short) -Short.MIN_VALUE == Short.MIN_VALUE // true
示例:
推荐阅读 点击标题可跳转Java 实现贪心算法实例介绍
Java 异步编程:内置功能与三方库
Java 并发:使用 AtomicReference 处理竞态条件
看完本文有收获?请转发分享给更多人
关注「ImportNew」,提升Java技能
好文章,我在看❤️