Can someone explain why
(0.1::Float) + (0.2::Float) == (0.3::Float)
while
(0.1::Double) + (0.2::Double) /= (0.3::Double)
To my knowledge Double is supposed to be more precise. Is there something about Float I should know about?
The first thing to realize is that when you enter 0.1::Double
and ghci prints 0.1
back, it's only an "illusion:"
Prelude Data.Ratio> 0.1::Double
0.1
Why is that an illusion? Because the number 0.1
is actually not precisely representable as a floating point number! This is true for both Float
and Double
. Observe:
Prelude Data.Ratio> toRational (0.1::Float)
13421773 % 134217728
Prelude Data.Ratio> toRational (0.1::Double)
3602879701896397 % 36028797018963968
So, in reality, these numbers are indeed "close" to the actual real number 0.1
, but neither is precisely 0.1
. How close are they? Let's find out:
Prelude Data.Ratio> toRational (0.1::Float) - (1%10)
1 % 671088640
Prelude Data.Ratio> toRational (0.1::Double) - (1%10)
1 % 180143985094819840
As you see, Double
is indeed a lot more precise than Float
; the difference between the representation of 0.1
as a Double
and the actual real-number 0.1
is a lot smaller. But neither is precise.
So, indeed the Double
addition is a lot more precise, and should be preferred over the Float
version. The confusing equality you see is nothing but the weird effect of rounding. The results of ==
should not be trusted in the floating-point land. In fact, there are many floating point numbers x
such that x == x + 1
holds. Here's one example:
Prelude> let x = -2.1474836e9::Float
Prelude> x == x + 1
True
A good read on floating-point representation is the classic What Every Computer Scientist Should Know about Floating-Point Arithmetic, which explains many of these quirky aspects of floating-point arithmetic.
Also note that this behavior is not unique to Haskell. Any language that uses IEEE754 Floating-point arithmetic will behave this way, which is the standard implemented by modern microprocessors.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With