为什么下面的代码打印2147483647,实际值是2147483648?
i = (int)Math.pow(2,31) ;
System.out.println(i);
Run Code Online (Sandbox Code Playgroud)
我知道int可以容纳的最大正值是2147483647.那么为什么像这样的代码自动换向负面并打印-2147483648?
i = (int)Math.pow(2,31) +1 ;
System.out.println(i);
Run Code Online (Sandbox Code Playgroud)
我是Integer类型.如果第二个代码示例(添加两个整数)如果结果超出正范围可以包装到负侧,为什么第一个样本不能包装?还有,
i = 2147483648 +1 ;
System.out.println(i);
Run Code Online (Sandbox Code Playgroud)
这与第二个代码示例非常相似会抛出编译错误,说第一个文字超出整数范围?我的问题是,根据第二个代码示例,为什么第一个和第三个样本不能自动换行到另一个?
mdm*_*dma 12
对于第一个代码示例中,结果是从窄double到int.在JLS 5.1.3介绍了如何进行的双打整数收缩转换.
相关部分是:
该值必须太大(大幅度或正无穷大的正值),第一步的结果是int或long类型的最大可表示值.
这就是2 ^ 31(2147483648)减少为Integer.MAX_VALUE(2147483647)的原因.同样如此
i = (int)(Math.pow(2,31)+100.0) ; // addition note the parentheses
Run Code Online (Sandbox Code Playgroud)
和
i = (int)10000000000.0d; // == 2147483647
Run Code Online (Sandbox Code Playgroud)
如果在没有括号的情况下完成添加,就像在第二个示例中那样,我们将处理整数加法.积分类型使用2的补码来表示值.在这个方案下加1
0x7FFFFFFF (2147483647)
Run Code Online (Sandbox Code Playgroud)
给
0x80000000
Run Code Online (Sandbox Code Playgroud)
这是-2147483648的2的补码.某些语言对算术运算执行溢出检查(例如,Ada将抛出异常).Java,它的C遗产不会检查溢出.当算术运算溢出或下溢时,CPU通常会设置溢出标志.语言运行时可以检查此标志,但这会引入额外的开销,有些人认为这是不必要的.
第三个示例不编译,因为编译器根据其类型范围检查文字值,并为超出范围的值提供编译器错误.请参阅JLS 3.10.1 - 整数文字.
| 归档时间: |
|
| 查看次数: |
553 次 |
| 最近记录: |