SQLite Forum

SQLite3 Extension
Login
The "machine epsilon" is different from the value epsilon.  The machine epsilon is the difference between 1 and the very next representible value.

The useful value is the "epsilon" of a value.  This is the absolute difference associated with "toggling" the last bit of the significand on and off, or the value of the Unit in the Last Place (ULP).

The expression abs(X - Y) > epsilon() tells you nothing (and is quite stupid, unless X happens to be 1).  

What you need to know is the number of ULPs between the X and Y which would require calculating the ULP of X and using that as the divisor of the subtraction.  This will tell you the number of ULP of X by which Y differs from X, and this is a useful number.  If it is 5 then X and Y are pretty damn close to equal.  If it is 5 million, then X and Y are not very close to each other at all.  And the sign of the result tells you which one is bigger.

IEEE-754 compliant floating point arithmetic requires that all operations be carried out to within 1 ULP (the actual requirement is that they be computed exactly and then rounded to the nearest representible value, which is slightly different).  This means that the difference between X and Y should be measured in the ULP distance between X and Y in based on the ULP of X.  While machine epsilon might be helpful here, it would be perspicacious to simply compute the ULP of X directly (since epsilon is merely the ULP of 1 -- why go to all the extra complication).

Assuming that one has a floating point value X in IEEE-754 base 2 representation, one would compute the "ULP" value of that represesentation by merely subtracting from the exponent the "number of bits" in the significand, and setting the significand to 1.  Similar methods can be used for other bases.

That is:

```
static __inline double epsilon(double value, int significand)
{
    int exponent;
    double mantissa = frexp(value, &exponent);
    return ldexp(1.0, exponent - significand);
}
```

where for "double precision IEEE-754" the value of significand is 53.  Note that you can compute this entirely without the math library, but since you already have it, why not use it.

Note also that there is a function for returning the correct fractional part and integer part of a floating point number and that function is modf.  While your "simple" method of computation may produce results that are accurate to within a boulder of salt, the modf function is guaranteed to produce results accurate to 1 ULP on IEEE-754 compliant systems.