Puzzle 86: Poison-Paren Litter
括号有毒-_-!
括号有毒-_-!
以下是本问题用到的两个类:
public class PoisonParen {
int i = -(2147483648);
}
public class PoisonParen {
long j = -(9223372036854775808L);
}
无论是 Eclipse 还是 NetBeans 都提醒了数值过大,可是 -2147483648 = -2^31 == Integer.MIN_VALUE
,为啥会出现这样的情况呢?
以上是 Eclipse 的
以上是 NetBeans 的
嗯,把括号去掉试试,好了,IDE 不报错,完全正常!
看来罪魁祸首是那对括号了,对,确实是它!一般情况下,加括号都是没有害处的,但这里,因为加了括号,就相当于写了一个 int 整数:2147483648,这个数比 Integer.MAX_VALUE
还大1,当然会报错。
Java语言中整数的范围
Java语言中整数的范围
在具体的语言中,比如 Java,整数是用范围的,亦Java的整数只是数学中定义的整数的一个子集,不然也不要搞个长整数(Long)了,虽然 Long 还是数学中定义的整数的一个子集,它们具体的取值范围如下:
Integer.MAX_VALUE = 2147483647 = 231-1
Integer.MIN_VALUE = -2147483648 = -231
Long.MAX_VALUE = 9223372036854775807 = 263 -1
Long.MIN_VALUE = -9223372036854775808 = -263
为何是这个范围?考虑到 int 是32位,long 是64位,数字位数太多,这里假设用四位来表示整数,观察它的表示情况:
以上表示的数的范围是 -8 ~ 7
,即-23 ~ 23-1
,可见在计算机中通过补码表示整数的话,用 n 位的话,表示的范围为 -2n-1 ~ 2n-1-1
.
附
- 相关的puzzle:Puzzle 33, Puzzle 64
- JLS 3.10.1,值得留意的是,这个规范只是说明了现象,只是描述性的,并不解释原因的,而具体原因,要参照本文中“Java语言中整数的范围”的说明。
- JAVA基础学习总结---原码、补码、反码以及基本数据类型 (by willzzs),这篇文里简单的提到了,补码即为反码加1. 而在JLS 15.15.4中更提到“For all integer values x, -x equals (~x)+1”。显然後者更为简单。