python 3.44 float addition bug?
buck
workitharder at gmail.com
Mon Jun 23 20:55:50 EDT 2014
It used to be that the best way to compare floating point numbers while disregarding the inherent epsilon was to use `str(x) == str(y)`. It looks like that workaround doesn't work anymore in 3.4.
What's the recommended way to do this now?
>>> format(.01 + .01 + .01 + .01 + .01 + .01, 'g') == format(.06, 'g')
True
On Saturday, June 21, 2014 12:24:24 PM UTC-7, Ned Deily wrote:
> In article
>
> <CAPTjJmrkPd5K__h9Qg12Q+AraFZVaN6eGUdTmEDGe2ccAqEmRw at mail.gmail.com>,
>
> Chris Angelico <rosuav at gmail.com> wrote:
>
> > Also, when you're looking at how things print out, consider looking at
>
> > two things: the str() and the repr(). Sometimes just "print(p)"
>
> > doesn't give you all the info, so you might instead want to write your
>
> > loop thus:
>
> >
>
> > z = 0.01
>
> > p = 0.0
>
> > for i in range(19):
>
> > p += z
>
> > print(str(p) + " -- " + repr(p))
>
> > Sometimes you can get extra clues that way, although in this instance
>
> > I think you won't.
>
>
>
> Actually, I think this is one case where you would get extra clues (or
>
> extra headscratching) if you run the code with various releases of
>
> Python.
>
>
>
> $ python2.6 b.py
>
> 0.01 -- 0.01
>
> 0.02 -- 0.02
>
> 0.03 -- 0.029999999999999999
>
> 0.04 -- 0.040000000000000001
>
> 0.05 -- 0.050000000000000003
>
> 0.06 -- 0.060000000000000005
>
> 0.07 -- 0.070000000000000007
>
> 0.08 -- 0.080000000000000002
>
> 0.09 -- 0.089999999999999997
>
> 0.1 -- 0.099999999999999992
>
> 0.11 -- 0.10999999999999999
>
> 0.12 -- 0.11999999999999998
>
> 0.13 -- 0.12999999999999998
>
> 0.14 -- 0.13999999999999999
>
> 0.15 -- 0.14999999999999999
>
> 0.16 -- 0.16
>
> 0.17 -- 0.17000000000000001
>
> 0.18 -- 0.18000000000000002
>
> 0.19 -- 0.19000000000000003
>
>
>
> $ python2.7 b.py
>
> 0.01 -- 0.01
>
> 0.02 -- 0.02
>
> 0.03 -- 0.03
>
> 0.04 -- 0.04
>
> 0.05 -- 0.05
>
> 0.06 -- 0.060000000000000005
>
> 0.07 -- 0.07
>
> 0.08 -- 0.08
>
> 0.09 -- 0.09
>
> 0.1 -- 0.09999999999999999
>
> 0.11 -- 0.10999999999999999
>
> 0.12 -- 0.11999999999999998
>
> 0.13 -- 0.12999999999999998
>
> 0.14 -- 0.13999999999999999
>
> 0.15 -- 0.15
>
> 0.16 -- 0.16
>
> 0.17 -- 0.17
>
> 0.18 -- 0.18000000000000002
>
> 0.19 -- 0.19000000000000003
>
>
>
> $ python3.4 b.py
>
> 0.01 -- 0.01
>
> 0.02 -- 0.02
>
> 0.03 -- 0.03
>
> 0.04 -- 0.04
>
> 0.05 -- 0.05
>
> 0.060000000000000005 -- 0.060000000000000005
>
> 0.07 -- 0.07
>
> 0.08 -- 0.08
>
> 0.09 -- 0.09
>
> 0.09999999999999999 -- 0.09999999999999999
>
> 0.10999999999999999 -- 0.10999999999999999
>
> 0.11999999999999998 -- 0.11999999999999998
>
> 0.12999999999999998 -- 0.12999999999999998
>
> 0.13999999999999999 -- 0.13999999999999999
>
> 0.15 -- 0.15
>
> 0.16 -- 0.16
>
> 0.17 -- 0.17
>
> 0.18000000000000002 -- 0.18000000000000002
>
> 0.19000000000000003 -- 0.19000000000000003
>
>
>
> What's going on here is that in Python 2.7 the repr() of floats was
>
> changed to use the minimum number of digits to accurately roundtrip the
>
> number under correct rounding. For compatibility reasons, the str()
>
> representation was not changed for 2.7. But in Python 3.2, str() was
>
> changed to be identical to repr() for floats. It's important to keep in
>
> mind that the actual binary values stored in float objects are the same
>
> across all of these releases; only the representation of them as decimal
>
> characters varies.
>
>
>
> https://docs.python.org/2.7/whatsnew/2.7.html#other-language-changes
>
>
>
> http://bugs.python.org/issue9337
>
>
>
> --
>
> Ned Deily,
>
> nad at acm.org
More information about the Python-list
mailing list