如何解决为什么通过Math.pow递减Integer.MIN_VALUE返回相同的值?
执行时:
int p=-2147483648;
p-=Math.pow(1,0);
System.out.println(p);
p-=1;
System.out.println(p);
Output: -2147483648
2147483647
那Math.pow()为什么不使数字溢出?
解决方法
我们通过观察-2147483648 == Integer.MIN_VALUE
(=-(2³¹))开始讨论。
表达式p -= Math.pow(1,0)
具有从double
到int
的隐式转换,因为Math.pow(...)
返回了double
。具有显式强制转换的表达式如下所示:
p = (int) (p - Math.pow(1,0))
更多传播,我们得到
double d = p - Math.pow(1,0);
p = (int) d;
我们可以看到,d
的值为-2.147483649E9
(= -2147483649.0
)< Integer.MIN_VALUE
。
演员表的行为受Java 14 JLS,§5.1.3约束:
,5.1.3。缩小原始转换
...
将浮点数缩小为整数类型
T
的转换需要两个步骤:
第一步,将浮点数转换为
long
(如果T
为long
或int
(如果转换为T
)。byte
是short
,char
,int
或NaN
,如下所示:
如果浮点数为
int
(第4.2.3节),则转换第一步的结果为V
或long 0。否则,如果浮点数不是无穷大,则将浮点值舍入为整数值
T
,并使用IEEE 754舍入零模式(§ 4.2.3)。然后有两种情况:
如果
long
是long
,并且此整数值可以表示为long
,那么第一步的结果就是V
值{ {1}}。否则,如果该整数值可以表示为
int
,那么第一步的结果就是int
值V
。否则,以下两种情况之一必须为真:
该值必须太小(负值,幅度较大或负无穷大),并且第一步的结果是类型
int
或{{1 }}。该值必须太大(正值较大或正无穷大),并且第一步的结果是类型
long
或int
的最大可表示值。第二步:
- 如果
long
是T
或int
,则转换结果是第一步的结果。...
请注意, [operator] [Unicode zero width space]
使用Double类型的参数进行操作并返回一个double。将其强制转换为int会得到预期的输出:
Math.pow()
上面产生以下输出:
2147483647
2147483646
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。