has quite some superfluous statements: 1. there's absolutely no need for 2 uint64_t holding |x| and |y|; 2. IEEE-754 specifies -0.0 == +0.0, so (x == y) is equivalent to (ax == 0) && (ay == 0): the latter 2 tests can be removed; 3. there's absolutely no need to compare the signs of x and y with the sign of the direction: its sufficient to test that direction and sign of x match; 4. a proper compiler/optimizer should be able to reuse the results of the comparision (x == y) for (x < y) or (x > y) and (x == 0.0) for (x < 0.0) or (x > 0.0). JFTR: if ((x < 0.0) == (x < y)) is equivalent to if ((x > 0.0) == (x > y)) --- -/src/math/nextafter.c +++ +/src/math/nextafter.c @@ -3,20 +3,15 @@ double nextafter(double x, double y) { union {double f; uint64_t i;} ux={x}, uy={y}; - uint64_t ax, ay; int e; if (isnan(x) || isnan(y)) return x + y; - if (ux.i == uy.i) + if (x == y) return y; - ax = ux.i & -1ULL/2; - ay = uy.i & -1ULL/2; - if (ax == 0) { - if (ay == 0) - return y; + if (x == 0.0) ux.i = (uy.i & 1ULL<<63) | 1; - } else if (ax > ay || ((ux.i ^ uy.i) & 1ULL<<63)) + else if ((x < 0.0) == (x < y)) ux.i--; else ux.i++;