5

I'm doing calculations with 3D vectors with floating point coordinates. Occasionally, I want to check if a vector is nonzero. However, with floating point numbers, there's always a chance of a rounding error.

Is there a standard way in Python to check if a floating point number is sufficiently close to zero? I could write abs(x) < 0.00001, but it's the hard-coded cutoff that bugs me on general grounds ...

NerdOnTour
  • 634
  • 4
  • 15
Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
  • this might be useful for you: http://stackoverflow.com/questions/9528421/value-for-epsilon-in-python – m.wasowski May 16 '15 at 13:30
  • 1
    `sys.float_info.epsilon` – Padraic Cunningham May 16 '15 at 13:33
  • 5
    @Seva Alekseyev It really depends on what you're doing, and I don't believe there's a general solution. Books like "Numerical Recipes in C" discuss precision ad-hoc per algorithm. I esp. disagree with these ``sys.float_info.epsilon`` comments above. They discuss the absolute system limits, not the limits of your particular calculation. – Ami Tavory May 16 '15 at 13:34

1 Answers1

4

Like Ami wrote in the comments, it depends on what you're doing. The system epsilon is good for single operation errors, but when you use already rounded values in further calculations, the errors can get much larger than the system epsilon. Take this extreme example:

import sys
print('%.20f\n' % sys.float_info.epsilon)
x = 0.1
for _ in range(25):
    print('%.20f' % x)
    x = 11*x - 1

With exact values, x would always be 0.1, since 11*0.1-1 is 0.1 again. But what really happens is this:

0.00000000000000022204

0.10000000000000000555
0.10000000000000008882
0.10000000000000097700
0.10000000000001074696
0.10000000000011821655
0.10000000000130038202
0.10000000001430420227
0.10000000015734622494
0.10000000173080847432
0.10000001903889321753
0.10000020942782539279
0.10000230370607932073
0.10002534076687252806
0.10027874843559780871
0.10306623279157589579
0.13372856070733485367
0.47101416778068339042
4.18115584558751685051
44.99271430146268357930
493.91985731608951937233
5432.11843047698494046926
59752.30273524683434516191
657274.33008771517779678106
7230016.63096486683934926987
79530181.94061353802680969238

Note that the original x differed from 0.1 by far less than my system epsilon, but the error quickly grew larger than that epsilon and even your 0.00001 and now it's in the millions.

This is an extreme example, though, and it's highly unlikely you'll encounter something this bad. But it shows that the precision really depends on what you're doing, so you'll have to find a good way for your particular calculation.

Stefan Pochmann
  • 27,593
  • 8
  • 44
  • 107
  • It's never a single operation. The example I was just looking at was a cross product of two vectors, where each one comes from subtracting two points from user input. Oh well... – Seva Alekseyev May 16 '15 at 18:23