Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly and standardly compare floats?

Every time I start a new project and when I need to compare some float or double variables I write the code like this one:

if (fabs(prev.min[i] - cur->min[i]) < 0.000001 &&     fabs(prev.max[i] - cur->max[i]) < 0.000001) {         continue; } 

Then I want to get rid of these magic variables 0.000001(and 0.00000000001 for double) and fabs, so I write an inline function and some defines:

#define FLOAT_TOL 0.000001 

So I wonder if there is any standard way of doing this? May be some standard header file? It would be also nice to have float and double limits(min and max values)

like image 463
Dmitriy Avatar asked Dec 28 '10 17:12

Dmitriy


People also ask

How do you compare two float values?

The compare() method of Float Class is a built-in method in Java that compares the two specified float values. The sign of the integer value returned is the same as that of the integer that would be returned by the function call. Parameters: The function accepts two parameters: f1: The first float value to be compared.

Can we use == to compare two float or double numbers?

The result of a floating-point comparison, as determined by the specification of the IEEE 754 standard, is: Floating-point equality testing is performed in accordance with the rules of the IEEE 754 standard: If either operand is NaN, then the result of == is false but the result of != is true.

Is it safe to compare floats?

The answer, of course, is “it depends”, but the most general answer is “no”. That is, suppose you are comparing two numbers x and y that are computed by two different floating-point algorithms, and you want a comparison function is_same(x,y) that returns true if you would have x==y in infinite precision.

How do you compare two floats in Python?

How To Compare Floats in Python. If abs(a - b) is smaller than some percentage of the larger of a or b , then a is considered sufficiently close to b to be "equal" to b . This percentage is called the relative tolerance. You can specify the relative tolerance with the rel_tol keyword argument of math.


2 Answers

From The Floating-Point Guide:

This is a bad way to do it because a fixed epsilon chosen because it “looks small” could actually be way too large when the numbers being compared are very small as well. The comparison would return “true” for numbers that are quite different. And when the numbers are very large, the epsilon could end up being smaller than the smallest rounding error, so that the comparison always returns “false”.

The problem with the "magic number" here is not that it's hardcoded but that it's "magic": you didn't really have a reason for choosing 0.000001 over 0.000005 or 0.0000000000001, did you? Note that float can approximately represent the latter and still smaller values - it's just about 7 decimals of precision after the first nonzero digit!

If you're going to use a fixed epsilon, you should really choose it according to the requirements of the particular piece of code where you use it. The alternative is to use a relative error margin (see link at the top for details) or, even better, or compare the floats as integers.

like image 128
Michael Borgwardt Avatar answered Sep 30 '22 14:09

Michael Borgwardt


The Standard provides an epsilon value. It's in <limits> and you can access the value by std::numeric_limits<float>::epsilon and std::numeric_limits<double>::epsilon. There are other values in there, but I didn't check what exactly is.

like image 43
Puppy Avatar answered Sep 30 '22 14:09

Puppy