rint.c 489 B

12345678910111213141516171819202122232425262728
  1. #include <float.h>
  2. #include <math.h>
  3. #include <stdint.h>
  4. #if FLT_EVAL_METHOD==0 || FLT_EVAL_METHOD==1
  5. #define EPS DBL_EPSILON
  6. #elif FLT_EVAL_METHOD==2
  7. #define EPS LDBL_EPSILON
  8. #endif
  9. static const double_t toint = 1/EPS;
  10. double rint(double x)
  11. {
  12. union {double f; uint64_t i;} u = {x};
  13. int e = u.i>>52 & 0x7ff;
  14. int s = u.i>>63;
  15. double_t y;
  16. if (e >= 0x3ff+52)
  17. return x;
  18. if (s)
  19. y = x - toint + toint;
  20. else
  21. y = x + toint - toint;
  22. if (y == 0)
  23. return s ? -0.0 : 0;
  24. return y;
  25. }