6
Python 2.7.3 (v2.7.3:70274d53c1dd, Apr  9 2012, 20:52:43) 
[GCC 4.2.1 (Apple Inc. build 5666) (dot 3)] on darwin
Type "copyright", "credits" or "license()" for more information.
>>> 4.2 - 1.8
2.4000000000000004
>>> 1.20 - 1.18
0.020000000000000018
>>> 5.1 - 4
1.0999999999999996
>>> 5 - 4
1
>>> 5.0 - 4.0
1.0

Why is Python getting its maths wrong?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
gadgetmo
  • 3,058
  • 8
  • 27
  • 41
  • [floating points](http://en.wikipedia.org/wiki/Floating_point) do not cover all real numbers, how could they? In any non-trivial range there are infinite number of real (and even rational) numbers, but only finite number of bits to represent them. So the python's math is correct - for floating points arithmetics. – amit Aug 14 '12 at 10:58
  • 3
    Read the section 14.1 of this link: http://docs.python.org/tutorial/floatingpoint.html – mvillaress Aug 14 '12 at 10:58
  • 4
    Python maths is not wrong. You don't understand the representation of floating-point numbers on computers nor the arithmetic of such numbers. Read the resources suggested by other commenters. – High Performance Mark Aug 14 '12 at 11:03
  • 5
    Python maths **is** wrong, mathematically speaking. It's just that being perfectly right all the time is computationally infeasible (numbers like `sqrt(2)` aren't even representable in a finite amount of space without directly coding them as things like `sqrt(2)`). The errors in Python's floating point arithmetic have been accepted as "the way it is done" for a very long time, and we just have to live with that as a matter of pragmatism. It is very very important for programmers to be aware of this, but we all have this moment of confusion. – Ben Sep 19 '12 at 06:09
  • 1
    All the delete voters, please don't delete a question that serves as a great signpost to users experiencing similar problems – jamylak Jun 11 '13 at 06:04
  • All other programming languages have the same basic problem. I remember first seeing this in CBM Basic on a Commodore PET2000 in the late seventies... – Ber Jun 14 '13 at 15:06
  • Python maths is/was wrong because they chose to use the C floating point library for their math, and the library they chose had this behaviour. Wrong as in, of all the infinite number of fixed point numbers they could have choosen to map to the floating point number, they choose a number that was certainly not the one that would have been given by exact arithmetic. I thought it was fixed in Python 3.x by use of a dedicated math library? – david Apr 23 '14 at 09:00
  • @david the problem is endemic to using binary floating point representations. Simple operations such as add/ subtract/ multiply/ divide don't use a library, they're a single CPU instruction. There's a `Decimal` module that works in decimal notation instead, but it's not the default as it's much slower. The same module is available in Python 2. – Mark Ransom Apr 24 '14 at 03:42
  • @Mark Ransom The problem is endemic when people use floating point math that they don't understand, to do things that they don't understand. Have a look at https://docs.python.org/3/tutorial/floatingpoint.html Work back from "Starting with Python 3.1, Python (on most systems) is now able to choose the shortest of these and simply display 0.1." – david Apr 28 '14 at 00:41
  • 1
    @david just because Python changed the way they choose to round a number for display doesn't mean the problem went away, just that they're doing a better job of hiding it. Nothing was actually fixed. And in case I wasn't clear, this has nothing to do with being based on C libraries, it's just the way processors work. I agree that many people don't understand the way binary floating point works, but that's unlikely to change as binary floating point is so unintuitive. – Mark Ransom Apr 28 '14 at 03:26

2 Answers2

368

You have reached a new level in computer science, and you are coming of age.

You therefore are now ready for the next step. I have been authorized by the BDFL himself to reveal the following Super Secret document to you. The ancients understood it and deciphered it first, and now, so will you!

The Floating Point Guide

Treat this document with care! Only share this with people you know have reached the same baffling conclusions!


Moderator's Note

This answer is not representative of the expected quality standards on Stack Overflow. However, it has unexpectedly developed a life of its own and is solely preserved for historical significance now.

Community
  • 1
  • 1
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 8
    what is BDFL.?! – Sid Apr 14 '15 at 09:33
  • 5
    @Sid: http://en.wikipedia.org/wiki/Benevolent_dictator_for_life – Martijn Pieters Apr 14 '15 at 09:46
  • 8
    Can you please summarize the link you've included? Link only answers are generally frowned upon. – TankorSmash Apr 19 '15 at 15:16
  • 1
    @TankorSmash: that kind-off would defeat the whole point here. You did see that first comment on this answer, right? – Martijn Pieters Apr 19 '15 at 15:18
  • 3
    @MartijnPieters It's a wide topic sure, but it would benefit the site to have some context to the link. I mean, 79 other people could be wrong, but I stand with them in saying this answer should be improved. – TankorSmash Apr 19 '15 at 16:25
  • 7
    @TankorSmash: you are missing the whole point here. Note that any anonymous visitors arriving here (having googled "Python math is wrong") are redirected to the canonical post already, where all that information is already present. This post was never meant to be a serious answer, and it has started a life of its own. Like the [parsing HTML with regex answer](http://stackoverflow.com/a/1732454), this is not something entirely different. Summarising the linked content would materially alter that nature. – Martijn Pieters Apr 19 '15 at 17:00
  • 1
    @TankorSmash: and I see that the specific comment I referred to has been deleted; I wasn't referring to arshajii's comment here (which I answered directly but that's gone now too). My new comment will have to take their place then. – Martijn Pieters Apr 19 '15 at 17:01
  • @MartijnPieters Sorry I was mistaken then, having never been linked here by anyone, I just assumed it was a common question and the answer was appropriately useful. Thanks for explaining the situation. – TankorSmash Apr 19 '15 at 17:25
54

For a painfully-rigorous guide to how floating-point arithmetic works, complete instructions on how to calculate how large the errors in your answers will be, you need:

What Every Computer Scientist Should Know About Floating-Point Arithmetic

Once you've read that, you should go and look for notes on the 8087 specifically, because it implements IEEE 754 poorly and this can cause new exciting problems in your life.

Richard Barrell
  • 4,361
  • 2
  • 22
  • 16
  • 19
    IEEE 754 came to life after 8087. It seems harsh to criticise 8087 for failing to meet a standard that did not exist when it was invented! – David Heffernan Apr 22 '13 at 11:55
  • 2
    The 8087 was used as the basis for IEEE754. The 80387 and its successors then implemented IEEE 754. – HTTP 410 Nov 21 '13 at 16:44