似乎没有一个答案涉及为什么行为不同。17.32
1. 为什么会发生
您看到的 和 之间的行为差异是由于 IEEE-754 舍入规则造成的。17.32
17.33 & 17.31
应用的舍入规则:来自 Java™ 虚拟机规范 §2.8.1
Java 虚拟机的舍入操作始终使用 IEEE 754 舍入到最接近模式。不精确的结果将舍入到最接近的可表示值,并且关系将转到具有零最低有效位的值。这是 IEEE 754 默认模式。Java 虚拟机不提供任何更改浮点舍入方式的方法
2. 您的案例:
双精度为:(1 个符号位 + 11 个指数位 + 52 个分数位 = 64 位)。舍入后的内部表示形式如下:
1 [63] 11 [62-52] 52 [51-00]
Sign Exponent Fraction
17.31 --> 0 (+) 10000000011 (+4) 1.0001010011110101110000101000111101011100001010001111
17.32 --> 0 (+) 10000000011 (+4) 1.0001010100011110101110000101000111101011100001010010 //rounded up
17.33 --> 0 (+) 10000000011 (+4) 1.0001010101000111101011100001010001111010111000010100
3. 内部代表(证明):
17.31: (尾狮比较)
Actual: 1.00010100111101011100001010001111010111000010100011110...
Internal: 1.0001010011110101110000101000111101011100001010001111
17.32: (尾数比较)
Actual: 1.00010101000111101011100001010001111010111000010100011...
Internal: 1.0001010100011110101110000101000111101011100001010010 //round-up!
17.33: (尾数比较)
Actual: 1.00010101010001111010111000010100011110101110000101000...
Internal: 1.0001010101000111101011100001010001111010111000010100
4. 转换回十进制:
17.31 -> 17.309999999999998721023075631819665431976318359375...
17.32 -> 17.32000000000000028421709430404007434844970703125... //(was rounded up)
17.33 -> 17.3299999999999982946974341757595539093017578125...
(IEEE-754 分析工具)
5. 投长
编辑:在你的乘法步骤中,有一个因素在起作用,正如@Jeppe斯蒂格·尼尔森(Stig Nielsen)所说。FP 乘法(参考)步骤的结果执行自己的舍入-向最接近。这改变了哪些结果符合预期,哪些结果不符合预期,但原因仍然与上述完全相同。
最后,由于施法 ,截断发生,并留下您看到的结果。(long)
(1730, 1732, 1732)
缩小原始转换范围:Java™ 语言规范 §5.1.3
如果浮点数不是无穷大,则浮点值将舍入为整数值 V,并使用 IEEE 754 向零舍入模式舍入为零