5

I'm a bit confused of how this subtraction and summation work this way:

A = 5
B = 0.1
C = A+B-A

And I found the answer is 0.099999999999999645. Why the answer is not 0.1?

Erika Sawajiri
  • 1,136
  • 3
  • 13
  • 18
  • 3
    Try seraching for floating point math. – Antimony Jun 19 '13 at 04:58
  • 1
    http://stackoverflow.com/questions/316238/python-float-to-decimal-conversion – kylex Jun 19 '13 at 04:59
  • Floating point arithmetic is inherently inaccurate, because not all numbers can be expressed by a 32 or 64 bit value. What Every Computer Scientist Should Know About Floating-Point Arithmetic: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html – Patashu Jun 19 '13 at 04:59
  • Please have a look at [Floating Point Arithmetic: Issues and Limitations](http://docs.python.org/2/tutorial/floatingpoint.html) – Klaus-Dieter Warzecha Jun 19 '13 at 05:00

5 Answers5

4

This is a floating point rounding error. The Python website has a really good tutorial on floating point numbers that explains what this is and why it happens.

If you want an exact result you can:

  • try using the decimal module
  • format your result to display a set number of decimal places (this doesn't fix the rounding error):

    print "%.2f"%C

I also recommend reading "What Every Computer Scientist Should Know About Floating-Point Arithmetic" from Brian's answer.

John Lyon
  • 11,180
  • 4
  • 36
  • 44
2

Why the answer is not 0.1?

Floating point numbers are not precise enough to get that answer. But holy cow is it ever close!

I recommend that you read "What Every Computer Scientist Should Know About Floating-Point Arithmetic"

Brian Cain
  • 14,403
  • 3
  • 50
  • 88
2

You're seeing an artefact of floating point arithmetic, which doesn't have infinit precision. See this article for a full description of how FP maths works, and why you see rounding errors.

2

This is because of the so called epsilon value. This means that from x to x+E every floating point number is considered to be equal to x. You can read something about this value in this Q&A in python this epsilon value(E) depends on the magnitune of the number, you can always get it from numpy.spacing(x)

Community
  • 1
  • 1
Alexandru Barbarosie
  • 2,952
  • 3
  • 24
  • 46
  • Wrong. The epsilon depends on the magnitude of the number – John La Rooy Jun 19 '13 at 05:07
  • @gnibbler so you want to say it is not the same for 2 different float numbers? – Alexandru Barbarosie Jun 19 '13 at 05:10
  • It's the same for lots of float numbers near `0.0`. It's different for _most_ of the other floating point numbers. You need to combine the exponent with the lsb of the mantissa to find the epsilon for a particular number. – John La Rooy Jun 19 '13 at 05:42
  • @gnibbler could you relate to a document containing that info? Because from what I've seen including in the some books, Q&A related in my answer is that this value is constant from language to language. – Alexandru Barbarosie Jun 19 '13 at 09:06
  • See [wikipedia](http://en.wikipedia.org/wiki/Floating_point#Machine_precision_and_backward_error_analysis). You see it is a relative error, so to get epsilon, you need to _divide by x_. Contrast this to fixed point where the epsilon represents an absolute error. – John La Rooy Jun 19 '13 at 10:35
  • @gnibbler but in the programming language, this epsilon is constant. But indeed, while the operations are performed by the processor it varies. Another [wiki article](http://en.wikipedia.org/wiki/Machine_epsilon#Approximation_using_Python) – Alexandru Barbarosie Jun 19 '13 at 10:42
  • 1
    You're misunderstanding what that article is saying. Try `np.spacing(x)` for different values of `x`, you will see that it is proportional to `x`. If you need more clarification, and you can't find an answer on here already you should open a new question. – John La Rooy Jun 19 '13 at 10:52
2

Computers use "binary numbers" to store information. Integers can be stored exactly, but fractional numbers are usually stored as "floating-point numbers".

There are numbers that are easy to write in base-10 that cannot be exactly represented in binary floating-point format, and 0.1 is one of those numbers.

It is possible to store numbers exactly, and work with the numbers exactly. For example, the number 0.1 can be stored as 1 / 10, in other words stored as a numerator (1) and a denominator (10), with the understanding that the numerator is divided by the denominator. Then a properly-written math library can work with these fractions and do math for you. But it is much, much slower than just using floating-point numbers, so it's not that often used. (And I think in banking, they usually just use integers instead of floating-point to store money; $1.23 can be stored as the number 123, with an implicit two decimal places. When dealing in money, floating point isn't exact enough!)

steveha
  • 74,789
  • 21
  • 92
  • 117