3

I was playing around with python when I tried

>>> Decimal(0.1)
Decimal('0.1000000000000000055511151231257827021181583404541015625')

which I thought was normal because of the floating point inaccuracy. I also expected that 0.1 * 10 would be slightly greater than 1.0

I then tried

>>> Decimal(0.1 * 10)
Decimal('1')
>>> 0.1 * 10 == 1.0
True

which is weird because they shouldn't be equal.

>>> sum = 0.0
>>> for i in range(10):
    sum += 0.1


>>> Decimal(sum)
Decimal('0.99999999999999988897769753748434595763683319091796875')

which is also weird because it's supposed to be slightly greater than 1.0

can someone explain this to me.

I am not sure if this is relevant but I used python 3.5.2 and python 2.7.12 on windows 8.1 64-bit.

Kareem
  • 33
  • 4
  • See my detailed answer to the same question here: http://stackoverflow.com/questions/40737008/floating-point-arithmetic-summation-versus-multiplication-of-error/ – Rick Regan Dec 09 '16 at 13:53

2 Answers2

6

The exact value of decimal 0.1 can't be represented in 64-bit binary floating-point, so it gets rounded to the nearest representable value, which is 0.1000000000000000055511151231257827021181583404541015625.

However, while the exact value of 0.1000000000000000055511151231257827021181583404541015625 * 10 can be represented in binary, it would take more bits of precision than 64-bit binary floating-point has. The result also gets rounded to the nearest representable value, and it turns out the nearest representable value is exactly 1.0.

Basically, you have two rounding errors, and they happen to cancel.

user2357112
  • 260,549
  • 28
  • 431
  • 505
  • Specifically, 1.000000000000000055511151231257827021181583404541015625 is closer to 1.0 than to 1.0000000000000002220446049250313080847263336181640625, the smallest 64-bit binary float greater than 1.0. – Patricia Shanahan Dec 09 '16 at 12:49
0

Please note, that in floating-point arithmetic, (in general) a+a+a is not equal to 3*a. Most of "normal" mathematical laws does not apply.

For multiplication there is other algorithm used instead of summing n times. This cause different round errors.

mbednarski
  • 758
  • 1
  • 9
  • 17