3

I'm relatively new to Python, and reading through a tutorial page on the documentation website, I came across this snippet:enter image description here This made me curious, so I decided to type it into a Python file and test it out. When I did this, however, it gave me a different result:

   .1+.1+.1 == .3
=> True

This question may seem trivial, but I'm curious why the actual behavior did not match what the Python documentation said it would do. Any answers?

This behavior occured while using an online interpreter. Running it locally returned False.

Jared Nielsen
  • 3,669
  • 9
  • 25
  • 36
  • 5
    The keyword here is *may* not. It depends on the floating point implementation of your platform. – Martijn Pieters Apr 19 '13 at 15:30
  • 1
    Shouldn't the same lines of code always yield the same result? – Jared Nielsen Apr 19 '13 at 15:31
  • 2
    No, they should not. Code is never run in isolation, what comes out depends on what you put in, and running code on Windows can have different results from running the same code on Unix systems, etc. – Martijn Pieters Apr 19 '13 at 15:32
  • 3
    [tag:ieee-754] is a good starting point to understand what can and cannot happen under the hood. – Mike Samuel Apr 19 '13 at 15:33
  • As @MartijnPieters said that depends on your platform. For example, different CPUs offer different approximation methods for floating point operations. Any floating point operation should be considered a platform-dependent approximation. – Florian Brucker Apr 19 '13 at 15:34
  • 1
    @jarednielsen, http://docs.python.org/2/reference/datamodel.html#types says "These represent machine-level double precision floating point numbers. You are at the mercy of the underlying machine architecture (and C or Java implementation) for the accepted range and handling of overflow." – Mike Samuel Apr 19 '13 at 15:35
  • Personally, I think the correct behavior for any compiler or interpreter testing floats for equality should be to terminate the program and print "You idiot, you're testing floats for equality." – Lee Daniel Crocker Apr 19 '13 at 15:36
  • `Shouldn't the same lines of code always yield the same result?` This is precisely *why* floating point errors are so frustrating- because what works on your computer might not work on your users' computers. (Ditto for OS-dependent code, time zones, anything to do with 32-bit vs 64-bit...) – David Robinson Apr 19 '13 at 15:36
  • Some things are internal and it is just better to use a fool proof algorithm rather than depending on non standard behaviour. Especially if it is mentioned in the documentation!! For example the print statement rounds off the florian point numbers. So it can lead to confusion sometimes!! – IcyFlame Apr 19 '13 at 15:42
  • 3
    @LeeDanielCrocker, as tempting as that would be, there are cases when floating point comparisons are really valid, for example when you want to know if a value changed from some previous saved value. – Mark Ransom Apr 19 '13 at 16:01
  • By the way, this returns `False` with 2.7 on my Windows PC and someone else reports that it returns `False` for them on Linux. What Python version and OS are you using? – Mark Ransom Apr 19 '13 at 16:02
  • Please tell us what Python version and OS you're using. Despite all the usual floating-point concerns, this is actually rather surprising behaviour on *any* version of Python / OS. – Mark Dickinson Apr 20 '13 at 12:32
  • @MarkRansom Sure. Sorry for the late response, but I've edited my original question to include a link to Codecademy Labs. – Jared Nielsen Apr 23 '13 at 21:21
  • 3
    This is another one of those questions that seems to be a duplicate of the countless "I don't get floating point" questions, but in fact has a twist. First, the OP has at least done the basic reading, and is even *expecting* floating point problems. Second, it turns out his environment was really at fault, not a misunderstanding of floats per se. So it's not truly a duplicate in my mind. However, is it worth trying to reopen this question just to get rid of its scarlet letter? That I'm not sure. – John Y Apr 23 '13 at 21:43
  • @LeeDanielCrocker There is already a GCC warning. The warning itself is, as you put it, idiotic. Just because you cannot see any use for something does not mean that everyone who might need it is an idiot. http://stackoverflow.com/questions/11421756/weverything-yielding-comparing-floating-point-with-or-is-unsafe – Pascal Cuoq May 01 '13 at 16:28
  • Not a duplicate of the question that it's marked as a duplicate of. A better match is http://stackoverflow.com/questions/6874357/why-0-1-0-2-0-3 – dan04 May 01 '13 at 16:41

2 Answers2

2

You never said which version of Python you're running, and that can make a huge difference. The arithmetic is likely to be IEEE based doubles which should be consistent from system to system. However CPython is based on underlying C libraries, and those can vary in the way they round floating-point constants as they're input. Other versions of Python will also be dependent on some underlying platform.

Edit: Confirmed. Using the online interpreter given in the question I get:

   '%0.20f' % (.1+.1+.1,)
=> '0.30000000000000004441'
   '%0.20f' % (.3,)
=> '0.30000000000000004441'

Using Python 2.7 on Windows:

>>> '%0.20f' % (.1+.1+.1,)
'0.30000000000000004441'
>>> '%0.20f' % (.3,)
'0.29999999999999998890'

It appears the online interpreter rounds the input differently.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
1

First comment is the answer. On my system:

Python 2.7.3 (default, Sep 26 2012, 21:53:58) 
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 0.1+0.1+0.1 == 0.3
False
>>>

from python docs (http://docs.python.org/2/tutorial/floatingpoint.html):

Binary floating-point arithmetic holds many surprises like this. The problem with “0.1” is explained in precise detail below, in the “Representation Error” section. See The Perils of Floating Point for a more complete account of other common surprises.

ndpu
  • 22,225
  • 6
  • 54
  • 69
  • Thanks. Do you know what factors would cause the code to return True on one computer and False on another? – Jared Nielsen Apr 19 '13 at 15:41
  • What does it matter? You won't realistically be able to do anything about the inconsistency, and anyway the proper and correct programming practice is to write the code in a way that doesn't care about the result of things like this. – Karl Knechtel Apr 19 '13 at 15:54
  • @jarednielsen added link to article in answer – ndpu Apr 19 '13 at 16:04
  • 1
    @KarlKnechtel, I think it's proper to question why your results should deviate from the official documentation no matter what best practice is. – Mark Ransom Apr 19 '13 at 16:50