Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ next float with numeric_limits / epsilon?

Consider a "normal" real number TREAL x in C++ (not subnormal and not NaN/Infinite) (TREAL = float, double, long double)
Is the following the good solution to find the previous and next x from a floating-point point of view ?

TREAL xprev = (((TREAL)(1.)) - std::numeric_limits<TREAL>::epsilon()) * x;
TREAL xnext = (((TREAL)(1.)) + std::numeric_limits<TREAL>::epsilon()) * x;

Thank you very much.

like image 643
Vincent Avatar asked Jun 22 '12 15:06

Vincent


2 Answers

C99 and C++11 have nextafter, nextafterl and nextafterf functions in <math.h> and <cmath>. Implementing them with basic arithmetic and epsilon would be tedious as you'd need to take rounding into account. Working on the binary representation is probably easier, but I wonder about the effect of the sign and magnitude representation and the existence of -0.0 (see Fred's answer for what is needed).

like image 104
AProgrammer Avatar answered Sep 22 '22 18:09

AProgrammer


Getting the next floating point number is a lot easier on the binary level:

float next(float f)
{
    unsigned x;
    memcpy(&x, &f, 4);
    ++x;
    memcpy(&f, &x, 4);
    return f;
}

Of course this will only work for systems where floating point numbers are stored "in ascending order", which happens to be the case for IEEE754.

Negative numbers will go towards negative infinity. Want them to go to zero instead? Use this:

float next(float f)
{
    int x;
    memcpy(&x, &f, 4);
    x += x >> 31 | 1;   // this will add 1 for positive f and -1 for negative f
    memcpy(&f, &x, 4);
    return f;
}
like image 43
fredoverflow Avatar answered Sep 22 '22 18:09

fredoverflow