Surprising difference for floating point arithmetic for Double vs Float
var num1 = 1.1
if num1 + 0.1 == 1.2 {print("true")} else {print("false")}
Result: false
var num1: Float = 1.1
if num1 + 0.1 == 1.2 {print("true")} else {print("false")}
Result: true
The previous code block has num1, which is a double, and the last code block has num1, which is a float.
My question is: Why does the code with Float return true and the other with Double not?
source to share
This is a duplicate and I will close it as such, but here's an example of why this works for Float
but not for Double
.
Instead of looking at Double
and Float
, consider two new types. Eighths
and Sixteenths
. Eighths
It has 3 bits to represent fractional numbers, so you can think of 0
, 0.125
, 0.25
, 0.375
, 0.5
, 0.625
, 0.75
and 0.875
. Sixteenths
It has 4 bits to represent fractional numbers, so you can think of 0
, 0.0625
, 0.125
, 0.1875
, 0.25
and so on. In both types of numbers, you will need to approximate floating point values by choosing the closest value to the one you want to represent.
So let's see what 1.1 + 0.1
looks like Eighths
and Sixteenths
.
Eighth
1.1 = 1.125 0.1 = 0.125 1.2 = 1.25 1.1 + 0.1 = 1.125 + 0.125 = 1.25
therefore 1.1 + 0.1 == 1.2
inEighths
sixteenth
1.1 = 1.125 0.1 = 0.125 1.2 = 1.1875 1.1 + 0.1 = 1.125 + 0.125 = 1.25
so 1.1 + 0.1 != 1.2
in Sixteenths
.
Higher precision Sixteenths
allows for more accurate representation 1.2
with a lower value represented in Sixteenths
.
This is what happens with Float
and Double
s. There are more bits available to represent numbers, but they are still getting closer. When you do math with these approximations, the error is bundled up in unexpected ways, so it's not a good idea to use comparable floating point values.
source to share