round.c 754 B

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. #include "libm.h"
  2. #if __FLT_EVAL_METHOD__ == 0 || __FLT_EVAL_METHOD__ == 1
  3. #define EPS __DBL_EPSILON__
  4. #elif __FLT_EVAL_METHOD__ == 2
  5. #define EPS __LDBL_EPSILON__
  6. #endif
  7. static const double toint = 1 / EPS;
  8. double round(double x)
  9. {
  10. union
  11. {
  12. double f;
  13. uint64_t i;
  14. } u = {x};
  15. int e = u.i >> 52 & 0x7ff;
  16. double y;
  17. if (e >= 0x3ff + 52)
  18. return x;
  19. if (u.i >> 63)
  20. x = -x;
  21. if (e < 0x3ff - 1)
  22. {
  23. /* raise inexact if x!=0 */
  24. FORCE_EVAL(x + toint);
  25. return 0 * u.f;
  26. }
  27. y = x + toint - toint - x;
  28. if (y > 0.5)
  29. y = y + x - 1;
  30. else if (y <= -0.5)
  31. y = y + x + 1;
  32. else
  33. y = y + x;
  34. if (u.i >> 63)
  35. y = -y;
  36. return y;
  37. }