java - 怀疑int变量的范围

标签 java integer-overflow

我对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 from 0 to 2147483647 may appear anywhere an int literal may appear, but the literal 2147483648 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/

相关文章:

java - 在 Swing 架上执行 Java 应用程序期间出现空白屏幕

java - 将 SelectItem[] 保存到 List<Hotel> 对象

java - 如何读取来自 HttpURLConnection 的完整响应?

java - 从另一个主方法中调用变量 - java

python - pandas/numpy int64 中意外的 32 位整数溢出(python 3.6)

java - 如何将远程CVS格式复制到本地文件eclipse?

c++ - C++14无符号整数溢出的进一步理解

c - 检测 C 中整数的溢出

python - 整数会在 Python 中溢出吗?

c - 如何在不进行类型转换的情况下通过乘法避免整数溢出?