The title is quite self-explanatory, input is given double value, and I want to add/substract the smallest amount possible.
-
Would `double next = value + std::numeric_limits
::epsilon() work` ? Or am I missing something? – rve Apr 15 '12 at 09:09 -
3@rve: At some point that stops increasing the value (has no effect), because the value you began with is a better approximation of the new value, which can't be precisely stored. So you get stuck in a loop of not quite reaching the next number. – GManNickG Apr 15 '12 at 09:27
-
1@rve, no, as it is epsilon for double with value 1, the epsilon gets bigger and bigger with higher numbers, see http://en.wikipedia.org/wiki/Double-precision_floating-point_format – kovarex Apr 15 '12 at 09:30
4 Answers
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.

- 494,350
- 52
- 494
- 543
-
-
@pmor The second parameter is a target, specifying direction, so you can just negate it. (Yes, this means the "next after" can go to the number before...it's not well named.) I realized this answer was a bit light on the details, let me know if this update clarifies. – GManNickG Aug 18 '21 at 17:36
Here's a very dirty trick that isn't actually legal and only works if your platform uses IEEE754 floats: The binary representation of the float is ordered in the same way as the float value, so you can increment the binary representation:
double x = 1.25;
uint64_t * const p = reinterpret_cast<uint64_t*>(&x);
++*p; // undefined behaviour! but it gets the next value
// now x has the next value
You can achieve the same effect entirely legally by doing the usual binary copy gymnastics to obtain a proper uint64_t
value. Make sure to check for zero, infinity and NaN properly, too.

- 464,522
- 92
- 875
- 1,084
-
1Will this handle correctly mantissa overflow ? What happens if the binary representation is .111111111 * 2^k ? Does it give .00000000 * 2^{k+1} ? – Alexandre C. Apr 15 '12 at 14:42
How about:
x += fabs(x) * std::numeric_limits<double>::epsilon();

- 28,429
- 12
- 61
- 81
-
Supposing you meant to add `::min()`, this won't work for denormalized numbers, and needs a proof for the regular case. What does IEEE 754 guarantee about ULPs under multiplication and addition? I would think that numbers `1.5*2^n ≤ x < 2^n+1` would round up to double the desired epsilon after the multiplication, although it should work with a fused multiply-add. – Potatoswatter Apr 15 '12 at 10:17
-
-
@DrewHall I also meant `epsilon`, not removing the downvote since the points still stand… – Potatoswatter Apr 16 '12 at 00:17
-
@Potatoswatter: I believe you're correct on both counts--it really depends on how rigorous the OP is trying to be. I'd call this the "70% solution" that would be good enough for most purposes. YMMV... – Drew Hall Apr 16 '12 at 01:15
#define FLT_MIN 1.175494351e-38F /* min positive value */
#define FLT_MAX 3.402823466e+38F /* max value */
#define DBL_MIN 2.2250738585072014e-308 /* min positive value */
#define DBL_MAX 1.7976931348623158e+308 /* max value */

- 1
- 1
-
1I think the OP wants to know the smallest possible *difference* between two float/double numbers, not the min/max values. – Alex Z Apr 15 '12 at 06:54
-
but it also shows how the minimum values are less than the ones stored in float.h file – dipal saluja Apr 15 '12 at 06:58
-
@AlexZ K. Then it depends on the FPU. The link I gave shows the precision to which FPU can process. And so I feel that the minimum difference can be the minimum positive value that can be processed – dipal saluja Apr 15 '12 at 07:02
-
2dipal saluja: No it is not, as the precision of floating point numbers decreases with size. – kovarex Apr 15 '12 at 07:11
-
2@dipalsaluja : Consider [this program](http://ideone.com/YgsJg). DBL_MIN is **not** the minimum difference between an arbitrarily-chosen value and its immediate successor. – Robᵩ Apr 15 '12 at 07:12
-
@Marwin: I would like to explore it in greater depth...Please share a link regarding this...Thanks!! – dipal saluja Apr 15 '12 at 23:39
-
@Robᵩ: ya as i said http://xona.com/2006/07/26.html shows how values less than the ones stored in float.h are possible :) – dipal saluja Apr 15 '12 at 23:40