将double乘以100,然后转换为long表示错误的值
我有以下代码:
Double i=17.31;long j=(long) (i*100);
System.out.println(j);
O / P: 1730 //Expected:1731
Double i=17.33;long j=(long) (i*100);
System.out.println(j);
O / P: 1732 //Expected:1733
Double i=17.32;long j=(long) (i*100);
System.out.println(j);
O / P: 1732 //Expected:1732{As expected}
Double i=15.33;long j=(long) (i*100);
System.out.println(j);
O / P: 1533 //Expected:1533{as Expected}
我已经尝试过使用Google,但是找不到原因。如果问题很简单,我们感到抱歉。
回答:
答案似乎都没有涉及 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所说,在您的乘法步骤中还有更多因素在起作用。 乘法(
)步骤的结果将其自身舍入为最接近的值。这种变化会产生预期的结果,而不会产生预期的结果,但是原因仍然与上述完全相同。
最后,由于强制转换(long)
,会发生截断,并使您看到的结果保留下来。(1730, 1732, 1732)
缩小原始转换:Java™语言规范
§5.1.3
如果浮点数不是无穷大,则将浮点值舍入为整数值V,并使用IEEE 754舍入为零模式舍入为零。
以上是 将double乘以100,然后转换为long表示错误的值 的全部内容, 来源链接: utcz.com/qa/401373.html