You can use nextafter
, which is available if your compiler implements C99's math functions (i.e., C++11 and above). This function (and its various overloads) can be described as:
double nextafter(double value, double target);
It will move from value
in the direction of target
by the smallest possible amount (typically by tweaking the bit representation of the float). If value
is already at target
, this does nothing.
If target
is greater than value
this will increment value
by the smallest possible amount. If target
is less than value
this will decrement value
by the smallest possible amount.
Common usage is to pass either DBL_MAX
or INFINITY
as the target to increase the minimal amount (or, the negation of them to decrease the minimal amount).
The choice between DBL_MAX
and INFINITY
depends on what you want to do at the boundary - nextafter(DBL_MAX, DBL_MAX) == DBL_MAX
, but nextafter(DBL_MAX, INFINITY) == INFINITY
.
And yes, it's poorly named. See also nextafter
and nexttoward
: why this particular interface?.
#include <cfloat> // DBL_MAX
#include <cmath> // std::nextafter
double x = 0.1;
// Next representable number **after** x in the direction of DBL_MAX.
// (i.e., this is larger than x, and there is no double between it and x)
double xPlusSmallest = std::nextafter(x, DBL_MAX);
// Next representable number **before** x in the direction of -DBL_MAX.
// (i.e., this is smaller than x, and there is no double between it and x)
double xMinusSmallest = std::nextafter(x, -DBL_MAX);
Even if your compiler doesn't support it, it probably has an instrinsic for it. (MSVC has had _nextafter
since 2005, for example. GCC probably implements it as standard.)
If your compiler doesn't support it but Boost is available to you, you can do this:
#include <boost/math/special_functions/next.hpp>
#include <cfloat>
double x = 0.1;
double xPlusSmallest = boost::math::nextafter(x, DBL_MAX);
double xMinusSmallest = boost::math::nextafter(x, -DBL_MAX);
And if none of those work for you, you'll just have to crack open the Boost header and copy it.