What's the closest double to 1.0, that isn't 1.0?
C++Floating PointFloating AccuracyC++ Problem Overview
Is there a way to programmatically get the double that is closest to 1.0, but isn't actually 1.0?
One hacky way to do this would be to memcpy the double to a same-sized integer, and then subtract one. The way IEEE754 floating-point formats work, this would end up decreasing the exponent by one while changing the fractional part from all zeros (1.000000000000) to all ones (1.111111111111). However there exist machines where integers are stored little-endian while floating-point is stored big-endian, so that won't always work.
C++ Solutions
Solution 1 - C++
Since C++11, you may use nextafter
to get next representable value in given direction:
std::nextafter(1., 0.); // 0.99999999999999989
std::nextafter(1., 2.); // 1.0000000000000002
Solution 2 - C++
In C and C++, the following gives the closest value to 1.0:
#include <limits.h>
double closest_to_1 = 1.0 - DBL_EPSILON/FLT_RADIX;
Note however that in later versions of C++, limits.h
is deprecated in favour of climits
. But then, if you are using C++ specific code anyway, you can use
#include <limits>
typedef std::numeric_limits<double> lim_dbl;
double closest_to_1 = 1.0 - lim_dbl::epsilon()/lim_dbl::radix;
And as Jarod42 writes in his answer, since C99 or C++11 you can also use nextafter
:
#include <math.h>
double closest_to_1 = nextafter(1.0, 0.0);
Of course in C++ you can (and for later C++ versions should) include cmath
and use std::nextafter
instead.
Solution 3 - C++
In C, you can use this:
#include <float.h>
...
double value = 1.0+DBL_EPSILON;
DBL_EPSILON
is the difference between 1 and the least value greater than 1 that is representable.
You'll need to print it to several digits in order to see the actual value.
On my platform, printf("%.16lf",1.0+DBL_EPSILON)
gives 1.0000000000000002
.
Solution 4 - C++
In C++ you can also use this
1 + std::numeric_limits<double>::epsilon()