What exactly is "exact" (was Clean Singleton Docstrings)

Chris Angelico rosuav at gmail.com
Mon Jul 18 06:37:23 EDT 2016


On Mon, Jul 18, 2016 at 8:24 PM, Rustom Mody <rustompmody at gmail.com> wrote:
> I dont know what point you are trying to make
> Here is behavior.  Should one use == ??
>
> Python 2.7.11+ (default, Apr 17 2016, 14:00:29)
> [GCC 5.3.1 20160413] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
>>>> .1+.1+.1 == .3
> False
>
> EPSILON = 0.000001 # Adjust to control numeric accuracy
> def is_equal(f1, f2, epsilon=EPSILON):
>     if abs(f1) > abs(f2):
>         f1, f2 = f2, f1
>     return abs(f2-f1) < f1*epsilon
>>>> ... ... ... ...
>
>>>> is_equal(.1+.1+.1, .3)
> True
>>>>

Sure, simple equality hasn't given you an "intuitive" result - but
that's because your source code is in decimal. So you need to properly
understand it. If you work with something that can be represented
precisely in binary, you have no problems with equality:

>>> 7/4 + 9/4 + 11/4 + 13/4 == 10
True

It's only the repeating values that have that problem. And if you
disassemble your example, it's obvious why you get False:

>>> dis.dis(lambda: .1+.1+.1 == .3)
  1           0 LOAD_CONST               4 (0.30000000000000004)
              2 LOAD_CONST               2 (0.3)
              4 COMPARE_OP               2 (==)
              6 RETURN_VALUE

Of course those two values aren't the same. And it'd be just as
obvious if you looked at them in binary. It'd look like this in
decimal:

0.6667 + 0.6667 + 0.6667 == 2.0

Well, duh, all those intermediate values are rounded up, so you're
getting the sum of the rounding, and of course it's not equal. That's
why you need to get some comprehension of floating-point and how it
*really* functions.

ChrisA



More information about the Python-list mailing list