java - 为什么 double 到 int 的转换在 java 中不能按预期工作?
问题描述
我已经开始阅读 Java8 的文档并尝试了不同的示例代码。发现下面的奇怪行为。
样品1
Double di = new Double(Math.pow(2,32-1));
System.out.printf("%f\n",di.doubleValue()); //2147483648.000000
int a= di.intValue();
System.out.println(a); //2147483647
样品2
Double di = new Double(Math.pow(2,32-1)) - 1.0;
System.out.printf("%f\n",di.doubleValue()); //2147483647.000000
int a= di.intValue();
System.out.println(a); //2147483647
为什么在这两种情况下,int 值都返回相同的值?
解决方案
请参阅https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.3最后以粗体突出显示的重要部分:
浮点数到整数类型 T 的窄化转换需要两个步骤:
第一步,浮点数转换为 long(如果 T 为 long)或转换为 int(如果 T 为 byte、short、char 或 int),如下所示:
如果浮点数是 NaN(第 4.2.3 节),则转换第一步的结果是 int 或 long 0。
否则,如果浮点数不是无穷大,则浮点值将四舍五入为整数值 V,使用 IEEE 754 向零舍入模式(第 4.2.3 节)向零舍入。那么有两种情况:
如果 T 是 long,并且这个整数值可以表示为 long,那么第一步的结果就是 long 值 V。
否则,如果这个整数值可以表示为 int,那么第一步的结果就是 int 值 V。
否则,以下两种情况之一必须为真:
该值必须太小(一个大的负值或负无穷大),第一步的结果是int或long类型的最小可表示值。
该值必须太大(一个大的正值或正无穷大),并且第一步的结果是 int 或 long 类型的最大可表示值。
也就是说,您的双精度值是 2147483648(您可以尝试使用更高的数字)。最高可表示值 int int是 2147483647。这就是你最终得到 2147483647 的原因。
推荐阅读
- c++ - 在 C++ 中获取字符的 ASCII 时出错
- regex - VBA中所有匹配项的RegEx数组/列表/集合
- javascript - 强制输入数字为科学计数法
- dialogflow-es - Dialogflow - 强制将 [Date][Number] 格式检测为日期和时间
- terraform - 如何从 terraform 中的不同文件导入数据源?
- java - 使用 launch4j 工具时 jfoenix lib 出错
- algorithm - 按组和日期对对象进行排序,并仅保留每个组中的最新对象
- c# - Galactic.ActiveDirectory 在 ASP MVC 中不起作用
- react-native - 如何仅使用 json 数据在本机反应中创建 UI?
- scala - 使用 Scala3 宏构建动态表达式