nextafter.c 712 B

1234567891011121314151617181920212223242526272829303132333435
  1. #include "libm.h"
  2. #define SIGN ((uint64_t)1<<63)
  3. double nextafter(double x, double y)
  4. {
  5. union dshape ux, uy;
  6. uint64_t ax, ay;
  7. int e;
  8. if (isnan(x) || isnan(y))
  9. return x + y;
  10. ux.value = x;
  11. uy.value = y;
  12. if (ux.bits == uy.bits)
  13. return y;
  14. ax = ux.bits & ~SIGN;
  15. ay = uy.bits & ~SIGN;
  16. if (ax == 0) {
  17. if (ay == 0)
  18. return y;
  19. ux.bits = (uy.bits & SIGN) | 1;
  20. } else if (ax > ay || ((ux.bits ^ uy.bits) & SIGN))
  21. ux.bits--;
  22. else
  23. ux.bits++;
  24. e = ux.bits >> 52 & 0x7ff;
  25. /* raise overflow if ux.value is infinite and x is finite */
  26. if (e == 0x7ff)
  27. FORCE_EVAL(x+x);
  28. /* raise underflow if ux.value is subnormal or zero */
  29. if (e == 0)
  30. FORCE_EVAL(x*x + ux.value*ux.value);
  31. return ux.value;
  32. }