问题
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