我对int值的范围有疑问
int x=2147483647; /*NO Error--this number is the maximum range
of int value no error*/
int y=2147483648; /*Error--one more than the
maximum range of int*/
int z=2147483647+1; /*No Error even though it is one more
than the maximum range value*/
为什么?
最佳答案
这是Java语言规范方面的解释。
整数文字部分 ( JLS 3.10.1 ) 是这样说的:
The largest decimal literal of type int is
2147483648
(231). All decimal literals from0
to2147483647
may appear anywhere an int literal may appear, but the literal2147483648
may appear only as the operand of the unary negation operator-
.
所以...
第一条语句是一个合法整数文字值的赋值。没有编译错误。
第二条语句是编译错误,因为
2147483648
前面没有一元否定运算符。第三条语句不包含超出范围的整数文字,因此从这个角度来看它不是编译错误。
相反,第三条语句是二进制加法表达式,如 JLS 15.18.2 中所述。 .这说明了以下有关整数情况的信息:
If an integer addition overflows, then the result is the low-order bits of the mathematical sum as represented in some sufficiently large two's-complement format. If overflow occurs, then the sign of the result is not the same as the sign of the mathematical sum of the two operand values.
因此,2147483647 + 1
溢出并环绕到 -2147483648
。
@Peter Lawrey 建议(轻率地?)第三条语句可以“由编译器重写”为 +2147483648
,从而导致编译错误。
这是不正确的。
JLS 中没有任何内容表明常量表达式可以与非常量表达式具有不同的含义。相反,在 1/0
这样的情况下,JLS 会颠倒过来并说该表达式不是常量表达式,因为它异常终止。 (在 JLS 15.28 中)
JLS 非常努力地避免某些 Java 构造意味着不同的东西的情况,具体取决于编译器。例如,它非常讲究“明确赋值”规则,以避免只有聪明的编译器才能推断出变量总是在使用前初始化的情况。从代码可移植性的角度来看,这是一件好事。
编译器实现者可以做平台特定事情的唯一重要领域是并发和 Java 内存模型领域。这有一个合理的实用理由 - 允许多线程 Java 应用程序在多核/多处理器硬件上快速运行。
关于java - 怀疑int变量的范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5140198/