小编典典

答案似乎都没有涉及 为什么 17.32采取不同的行动。

1.为什么发生

您看到的17.32和之间的行为差​​异17.33 & 17.31是由于IEEE-754 舍入 规则引起的。

应用的舍入规则:摘自Java™虚拟机规范

§2.8.1

Java虚拟机的舍入操作始终使用IEEE 754舍入到最近模式。不精确的结果四舍五入到最接近的可表示值,并用最低有效位为零的值舍入。这是IEEE

754的默认模式。Java虚拟机未提供任何方法来更改浮点舍入模式

2.您的情况:

Double是 :(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:(Mantissa比较)

Actual: 1.00010100111101011100001010001111010111000010100011110...

Internal: 1.0001010011110101110000101000111101011100001010001111

17.32:(Mantissa比较)

Actual: 1.00010101000111101011100001010001111010111000010100011...

Internal: 1.0001010100011110101110000101000111101011100001010010 //round-up!

17.33:(Mantissa比较)

Actual: 1.00010101010001111010111000010100011110101110000101000...

Internal: 1.0001010101000111101011100001010001111010111000010100

4.转换为小数:

17.31 -> 17.309999999999998721023075631819665431976318359375...

17.32 -> 17.32000000000000028421709430404007434844970703125... //(was rounded up)

17.33 -> 17.3299999999999982946974341757595539093017578125...

5.转换为长

编辑: 正如@Jeppe Stig Nielsen所说,在您的乘法步骤中还有更多因素在起作用。 FP 乘法(

最后,由于强制转换(long),会发生截断,并使您看到的结果保留下来。(1730, 1732, 1732)

缩小原始转换:Java™语言规范

§5.1.3

如果浮点数不是无穷大,则将浮点值舍入为整数值V,并使用IEEE 754舍入为零模式舍入为零。

2020-11-13

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐