Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to (portably) get DBL_EPSILON in C and C++

Tags:

c++

c

I am using GCC 3.4 on Linux (AS 3) and trying to figure out to get DBL_EPSILON, or at least a decent approximation. How can I get it programmatically?

like image 438
vehomzzz Avatar asked Oct 14 '09 13:10

vehomzzz


People also ask

Where is Dbl_epsilon defined?

C's DBL_EPSILON is the distance between 1 and the closest floating point number greater than 1. Said another way, DBL_EPSILON is the smallest positive floating point number x such that 1 + x != 1 , often called “machine epsilon.”


2 Answers

In C++ it's std::numeric_limits<double>::epsilon().

like image 103
sbi Avatar answered Sep 30 '22 19:09

sbi


It should be in "float.h". That is portable, it's part of the C and C++ standards (albeit deprecated in C++ - use <cfloat> or sbi's answer for "guaranteed" forward compatibility).

If you don't have it, then since your doubles are IEEE 64-bit, you can just steal the value from someone else's float.h. Here's the first one I found:

http://opensource.apple.com/source/gcc/gcc-937.2/float.h

#define DBL_EPSILON 2.2204460492503131e-16

The value looks about right to me, but if you want to be sure on your compiler, you could check that (1.0 + DBL_EPSILON) != 1.0 && (1.0 + DBL_EPSILON/2) == 1.0

Edit: I'm not quite sure what you mean by "programmatically". It's a standard constant, you aren't supposed to calculate it, it's a property of the implementation given to you in a header file. But I guess you could do something like this. Again, assuming IEEE representation or something like it, so that DBL_EPSILON is bound to be whatever power of 0.5 represents a 1 in the last bit of precision of the representation of 1.0:

double getDblEpsilon(void) {
    double d = 1;
    while (1.0 + d/2 != 1.0) {
        d = d/2;
    }
    return d;
}

Beware that depending on compiler settings, intermediate results might have higher precision than double, in which case you'd get a smaller result for d than DBL_EPSILON. Check your compiler manual, or find a way to force the value of 1.0 + d/2 to be stored and reloaded to an actual double object before you compare it to 1.0. Very roughly speaking, on PCs it depends on whether your compiler uses the x86 FPU instructions (higher precision), or newer x64 floating point ops (double precision).

like image 33
Steve Jessop Avatar answered Sep 30 '22 18:09

Steve Jessop