Java 为什么通过Math.pow()递减Integer.MIN_值会返回相同的值?
执行时:Java 为什么通过Math.pow()递减Integer.MIN_值会返回相同的值?,java,integer-overflow,Java,Integer Overflow,执行时: int p=-2147483648; p-=Math.pow(1,0); System.out.println(p); p-=1; System.out.println(p); Output: -2147483648 2147483647 那么为什么Math.pow()没有溢出这个数字呢?请注意Math.pow()使用Double类型的参数进行操作并返回一个Double。将其强制转
int p=-2147483648;
p-=Math.pow(1,0);
System.out.println(p);
p-=1;
System.out.println(p);
Output: -2147483648
2147483647
那么为什么Math.pow()没有溢出这个数字呢?请注意
Math.pow()
使用Double类型的参数进行操作并返回一个Double。将其强制转换为int将产生预期输出:
public class MyClass {
public static void main(String args[]) {
int p=-2147483648;
p-=(int)Math.pow(1,0);
System.out.println(p);
p-=1;
System.out.println(p);
}
}
上述操作产生以下输出:
2147483647
2147483646我们通过观察
-2147483648==Integer.MIN_值(=-(2)]开始讨论
表达式p-=Math.pow(1,0)
具有从double
到int
的隐式强制转换,因为它返回一个double
。带有显式强制转换的表达式如下所示
p = (int) (p - Math.pow(1,0))
更分散,我们得到
double d = p - Math.pow(1,0);
p = (int) d;
我们可以看到,d
的值为-2.147483649E9
(=-2147483649.0
)
演员的行为由以下因素决定:
5.1.3。缩小原语转换的范围
将浮点数缩小为整数类型T
需要两个步骤:
在第一步中,如果T
是long
,则将浮点数转换为long
,或者如果T
是byte
,short
,char
或int
,则将浮点数转换为int
,如下所示:
- 如果浮点数为
NaN
(§4.2.3),则转换的第一步结果为int
或长0
- 否则,如果浮点数不是无穷大,则使用IEEE 754向零舍入模式(§4.2.3)将浮点数舍入为整数值
V
,向零舍入。然后有两种情况:
- 如果
T
是long
,并且该整数值可以表示为long
,则第一步的结果是long
值V
- 否则,如果此整数值可以表示为
int
,则第一步的结果是int
值V
- 否则,以下两种情况之一必须为真:
- 该值必须太小(大幅度的负值或负无穷大),第一步的结果是
int
或long
类型的最小可表示值
- 该值必须太大(大幅度的正值或正无穷大),并且第一步的结果是
int
或long
类型的最大可表示值
第二步:
如果T
为int
或long
,则转换结果为第一步的结果
如果两个参数都是整数,那么结果正好等于将第一个参数提升为第二个参数的幂的数学结果,如果该结果实际上可以精确地表示为双精度值。[您可以阅读有关Math javadocs的更多信息][1][1]: