Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to choose epsilon value for floating point? [closed]

Since we know that 0.1 + 0.2 != 0.3 due to limited number representation, we need to instead check hat abs(0.1+0.2 - 0.3) < ε. The question is, what ε value should we generally choose for different types? Is it possible to estimate it depending on the number of bits and the number and types of operations that are likely to be performed?

like image 914
Dmitri Nesteruk Avatar asked Feb 02 '16 16:02

Dmitri Nesteruk


People also ask

What value should I use for epsilon?

The EPSILON property has a value of approximately 2.2204460492503130808472633361816E-16 , or 2-52.

How do I find the epsilon for floating point?

In general, if you look at a machine number with base b, mantissa m (and exponent e), you can define eps:=b1−m2. To your example: You would probably represent 4 normalized as (0.10000000)2⋅23. The next number 4+132 is then represented as (0.10000001)2⋅23, i.e. you have m=8 and thus eps=2−8.

How does epsilon compare to floats?

Epsilon comparisonsbool isEqual = fabs(f1 – f2) <= epsilon; With this calculation we can express the concept of two floats being close enough that we want to consider them to be equal.

Why epsilon is enough for floating point comparison checks?

By comparing floats to epsilon instead of zero, we're able to approximate their values and account for the minor rounding errors present in the floating point definition. Epsilon can be used to account for all kinds of inaccuracies with regards to floats, not just a comparison to zero.


2 Answers

A baseline value for epsilon is the difference between 1.0 and the next highest representable value. In C++, this value is available as std::numeric_limits<T>::epsilon().

Note that, at the minimum, you need to scale this value as a proportion of the actual number you're testing. Also, since the precision scales only roughly with the numeric value, you may want to increase your margin by a small factor to prevent spurious errors:

double epsilon = std::numeric_limits<double>::epsilon();

// C++ literals and math functions are double by default
bool is_near = abs(0.1+0.2 - 0.3) <= 0.3 * (2*epsilon);

As a more complete example, a function for comparing doubles:

bool is_approximately_equal(double a, double b) {
  double scale = max(abs(a), abs(b));
  return abs(a - b) <= scale * (2*epsilon);
}

In practice, the actual epsilon value you should use depends on what you're doing, and what kind of tolerance you actually need. Numeric algorithms will typically have precision tolerances (average and maximum) as well as time and space estimates. But the precision estimate typically starts with something like characteristic_value * epsilon.

like image 143
comingstorm Avatar answered Oct 01 '22 01:10

comingstorm


You can estimate the machine epsilon using the algorithm below. You need to multiply this epsilon with the integer value of 1+(log(number)/log(2)). After you have determined this value for all numbers in your equation, you can use error analysis to estimate the epsilon value for a specific calculation.

epsilon=1.0

while (1.0 + (epsilon/2.0) > 1.0) {
  epsilon = epsilon /2.0     
}
//Calculate error using error analysis for a + b
epsilon_equation=Math.sqrt(2*epsilon*epsilon)

document.write('Epsilon: ' + epsilon_equation+'<br>')
document.write('Floating point error: ' + Math.abs(0.2 + 0.4 -0.6)+'<br>')
document.write('Comparison using epsilon: ')
document.write(Math.abs(0.2 + 0.4 -0.6)<epsilon_equation)

Following your comment, I have tried the same approach in C# and it seems to work:

using System;

namespace ConsoleApplication
{
   
    public class Program
    {
        public static void Main(string[] args)
        {
            double epsilon = 1.0;

            while (1.0 + (epsilon/2.0) > 1.0)
            {
                epsilon = epsilon/2.0;
            }

            double epsilon_equation = Math.Sqrt(2*epsilon*epsilon);

            Console.WriteLine(Math.Abs(1.0 + 2.0 - 3.0) < Math.Sqrt(3.0 * epsilon_equation * epsilon_equation));
        }
    }
}
like image 36
Alex Avatar answered Oct 01 '22 01:10

Alex