Why is 0.29999999999999998 converted to 0.3?

☆樱花仙子☆ 提交于 2020-06-26 07:56:16

问题


How does it work internally?

How does it decide to convert 0.29999999999999998 to 0.3, even though 0.3 cannot be represented in binary?

Here are some more example:

scala> 0.29999999999999998
res1: Double = 0.3

scala> 0.29999999999999997
res2: Double = 0.3

scala> 0.29999999999999996
res3: Double = 0.29999999999999993

scala> 0.29999999999999995
res4: Double = 0.29999999999999993

回答1:


There are two conversions involved.

First 0.29999999999999998 is converted to 0.299999999999999988897769753748434595763683319091796875, the nearest representable number.

Next, 0.299999999999999988897769753748434595763683319091796875 is converted to decimal for printing. 0.3 is also one of the numbers that converts to 0.299999999999999988897769753748434595763683319091796875, and it is the one that gets printed because it is so short.

Every finite double number is exactly representable as a decimal fraction. Generally, default output does not attempt to print the exact value, because it can be very long - far longer than the example above. A common choice is to print the shortest decimal fraction that would convert to the double on input. Both conversions are done using non-trivial algorithms. See Algorithm to convert an IEEE 754 double to a string? for some discussion and references to output algorithms.

==============================================================

There has been some discussion in comments on the value 0.30000000000000004. I agree with the comments by Rick Regan and Jesper, but thought it might be useful to add to this answer.

The exact value of the closest double to 0.30000000000000004 is 0.3000000000000000444089209850062616169452667236328125. All decimal numbers in the range [0.3000000000000000166533453693773481063544750213623046875, 0.3000000000000000721644966006351751275360584259033203125] convert to that value, and no numbers even slightly outside that range do so. 0.3000000000000000 is outside the range, so it does not have enough digits. 0.30000000000000004 is inside the range, so there is no need for more digits to correctly identify the double.




回答2:


Note in Scala Double (see IEEE 754 Standard and IEEE Floating-Point Arithmetic), the original declared value is rounded up to nearest,

val x = 0.29999999999999998
x: Double = 0.3

"0.29999999999999998".toDouble
Double = 0.3

in as much as

0.2999999999999999999999999999999999999999999999999999999999998
Double = 0.3

Also in BigDecimal for arbitrary precision decimal floating-point representation (see API), the original value of type Double (parameter to the constructor) is first rounded up, namely

BigDecimal(0.29999999999999998) == 0.3
Boolean = true

BigDecimal(0.29999999999999998)
scala.math.BigDecimal = 0.3

However a textual declaration of the original value is not interpreted as Double and hence rounded up,

BigDecimal("0.29999999999999998") == 0.3
Boolean = false

namely,

BigDecimal("0.29999999999999998")
scala.math.BigDecimal = 0.29999999999999998


来源:https://stackoverflow.com/questions/34081470/why-is-0-29999999999999998-converted-to-0-3

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!