sat*_*esh 4 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*/
Run Code Online (Sandbox Code Playgroud)
为什么?
以下是Java语言规范的解释.
关于整数文字的部分(JLS 3.10.1)说:
int类型的最大十进制文字是
2147483648(2 31).来自0to的所有十进制文字都2147483647可能出现在int文字可能出现的任何地方,但文字2147483648只能作为一元否定运算符的操作数出现-.
所以......
第一个语句是一个合法的整数字面值的赋值.没有编译错误.
第二个语句是编译错误,因为2147483648前面没有一元否定运算符.
第三个语句不包含超出范围的整数文字,因此从该角度来看,它不是编译错误.
相反,第三个语句是JLS 15.18.2中描述的二进制加法表达式.这表示以下关于整数的情况:
如果整数加法溢出,则结果是数学和的低阶位,如某些足够大的二进制补码格式所示.如果发生溢出,则结果的符号与两个操作数值的数学和的符号不同.
因此,2147483647 + 1溢出和包裹到-2147483648.
@Peter Lawrey建议(轻率地?)第三个语句可能被"编译器重写" +2147483648,导致编译错误.
这是不正确的.
JLS中没有任何内容表明常量表达式对非常量表达式具有不同的含义.相反,在像1 / 0JLS翻转事物的情况下,表示表达式不是常量表达式,因为它异常终止.(见JLS 15.28)
JLS非常努力地避免某些Java构造意味着不同的情况,具体取决于编译器.例如,对于"明确赋值"规则非常特别,以避免只有智能编译器可以推断出该变量在使用之前始终被初始化的情况.从代码可移植性的角度来看,这是一件好事.
编译器实现者为平台特定事物提供"摆动空间"的唯一重要领域是并发和Java内存模型.并且有一个合理的实用理由 - 允许多线程Java应用程序在多核/多处理器硬件上快速运行.