Precision for equality of two floats?

A

Anton81

Hi!

When I do simple calculation with float values, they are rarely exactly
equal even if they should be. What is the threshold and how can I change
it?

e.g. "if f1==f2:" will always mean "if abs(f1-f2)<1e-6:"

Anton
 
F

Fredrik Lundh

Anton81 said:
When I do simple calculation with float values, they are rarely exactly
equal even if they should be. What is the threshold

http://www.lahey.com/float.htm
http://docs.python.org/tut/node16.html
and how can I change it?

you cannot.
e.g. "if f1==f2:" will always mean "if abs(f1-f2)<1e-6:"

use your own equal function, e.g.

def equal(a, b):
return abs(a - b) < 1e-6

if equal(f1, f2):
...

(see the "safe comparision" section of the lahey.com paper
for better ways to test for "approximate equality")

</F>
 
A

Alex Martelli

Anton81 said:
Hi!

When I do simple calculation with float values, they are rarely exactly
equal even if they should be. What is the threshold and how can I change
it?

Python's builtin floats compare for exact bit-by-bit equality -- no
"threshold". You may want to look at the allclose function in the
Numeric extension package, at least for its specs (it consider both
absolute and relative difference). Extension module gmpy might also
help, since its mpf floating numbers implement a fast reldiff (relative
difference) method.


Alex
 
M

Mike Meyer

Anton81 said:
When I do simple calculation with float values, they are rarely exactly
equal even if they should be. What is the threshold and how can I change
it?

Implementation dependent, because floats use an underlying C type, and
there's no portable way to do that.
e.g. "if f1==f2:" will always mean "if abs(f1-f2)<1e-6:"

This is a *bad* idea. What happens if f1=1e-12 and f2=1e-112? Do you
really want to values that 100 orders of magnitude different to
compare as equal? You should use something like "if abs(f1 - f2) <
abs(f1) * 1e-6" (been a long time since I worried about this; there's
probably a better version).

DSepending on why you need it, you might consider using decimals
(introduced in 2.4) instead of floats.

<mike
 
S

Steven D'Aprano

This is a *bad* idea. What happens if f1=1e-12 and f2=1e-112? Do you
really want to values that 100 orders of magnitude different to
compare as equal?

Sure, if f1 and f2 represent quantities like "average number of people,
in millions", both should be considered as more or less zero. It is a
little hard to justify treating one millionth of a person as a meaningful
figure, no matter how accurate your model for population growth might be.

For the avoidance of confusion, I am *not* suggesting that == for floats
should have any other behaviour other than the one it has now, merely that
the developer rarely wants to use == for comparing floats.

Floating point equality is usually application-specific. Not only do
the floats themselves have only finite resolution, but often you don't
even care about that full resolution since it simply introduces spurious
accuracy not justified by either your model or your data.
You should use something like "if abs(f1 - f2) <
abs(f1) * 1e-6" (been a long time since I worried about this; there's
probably a better version).

Sometimes you want relative differences, sometimes you care about absolute
differences, and sometimes -- very rarely -- you actually want full-blown
bit-for-bit equality.
 
B

Bengt Richter

Python's builtin floats compare for exact bit-by-bit equality -- no
"threshold". You may want to look at the allclose function in the
Does "exact bit-by-bit" mean that

a = <floatexpr>
a == <floatexpr>

is 100% guaranteed? I.e., are there implementations where an expression
value might remain in 80-bit representation in the fpu and be rounded
to 64 bits for assignment to a and then not compare equal because the second
a is a rounded 64-bit value compared to the regenerated 80-bit value?

Since cpython bytecodes store expression values on the cpu stack, not
the fpu stack, I assume it's ok there, but is it a potential problem
for optimizers generating machine code? Or is it spec-ed for mandatory
as-if-storing-both-arguments-as-double-before-comparing behaviour?

Just wondering ;-)

Regards,
Bengt Richter
 
D

Dan Sommers

On Tue, 29 Nov 2005 14:31:46 GMT,
Does "exact bit-by-bit" mean that
a = <floatexpr>
a == <floatexpr>
is 100% guaranteed? I.e., are there implementations where an
expression value might remain in 80-bit representation in the fpu and
be rounded to 64 bits for assignment to a and then not compare equal
because the second a is a rounded 64-bit value compared to the
regenerated 80-bit value?

IIRC, if you consider NaNs, then a == a isn't even guaranteed if a might
be a NaN, but that's probably Too Much Information. ;-)

There have been (and may well still be) seemingly endless debates about
this on comp.std.c (even without the possibility of NaNs, for similar
reasons to the one you cite). I don't know if the Lisp and/or IEEE-754
crowds have worked all of this out.

Regards,
Dan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,743
Messages
2,569,478
Members
44,899
Latest member
RodneyMcAu

Latest Threads

Top