0

When I run the following code, I am surprised to see that subtracting DBL_MIN (the "minimum normalized positive value", around 2.2250738585072014e-308), which is supposed to be the lowest positive double, has no effect. Doing the same with DBL_TRUE_MIN has no effect either.

How should I go about getting the highest double lower to (double)upper_bound?

Code:

#include <stdio.h>
#include <float.h>

int main(void) {
  // lower_bound ≤ x < upper_bound
  long int lower_bound = 0L;
  long int upper_bound = 50L;
  // x_lo ≤ x ≤ x_hi
  double x_lo = (double)lower_bound;
  double x_hi = ((double)upper_bound) - DBL_MIN;
  if (x_hi < upper_bound)
    printf("x_hi < upper_bound: SUCCESS\n");
  else if (x_hi > upper_bound)
    printf("x_hi > upper_bound: FAILURE\n");
  else
    printf("x_hi == upper_bound: FAILURE\n");
}

Output:

x_hi == upper_bound: FAILURE
Maxime
  • 38
  • 1
  • 6
  • 1
    Despite the C to C++ language difference, I feel the duplicate is relevant, because [nextafter is also available in C](https://en.cppreference.com/w/c/numeric/math/nextafter). – Adrian Mole Aug 10 '22 at 08:47
  • I wonder if this is some compiler / CPU being a bit cheeky. Some FPUs, and especially SIMD units (e.g. SPEs on Cell processors) will take shortcuts in the interest of speed over strict arithmetic accuracy. After all, it doesn't matter if a pixel is shaded ever so slightly wrong... Maybe the FPU is getting part way through the subtraction, gets to a level of precision, and assumes that the accuracy achieved is likely sufficient. I agree that your program output should be SUCCESS, but the hardware might be conspiring against this. It would be interesting to substitute in nextafter(), to see. – bazza Aug 10 '22 at 09:01
  • Are you sure that substracting the smallest normal double gives a different number ? It might be true bit it is not obvgious to me. – Guillaume Petitjean Aug 10 '22 at 10:01
  • I think your assumption is wrong: substracting the smallest normal double from another double does not give necesarrilly a different number. For example (from wikipedia) for 32 bits float number in IEEE754: the number 1 has an exact representation. the next number following 1 (the closest higher number) is 1,000 000 12. The difference between both successive numbers is far larger than the smaller normal number which is 1,4 × 10−45 – Guillaume Petitjean Aug 10 '22 at 10:07
  • So something like `double x_hi = nextafter(upper_bound, x_lo);` should work. Add `#include ` and add `-lm` to the compiler command line for traditional Unix-style C compilers to link the math library. – Ian Abbott Aug 10 '22 at 11:23

0 Answers0