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?

+3


source to share


1 answer


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.

+1


source







All Articles