modf.c 536 B

12345678910111213141516171819202122232425262728293031323334
  1. #include "libm.h"
  2. double modf(double x, double *iptr)
  3. {
  4. union {double f; uint64_t i;} u = {x};
  5. uint64_t mask;
  6. int e = (int)(u.i>>52 & 0x7ff) - 0x3ff;
  7. /* no fractional part */
  8. if (e >= 52) {
  9. *iptr = x;
  10. if (e == 0x400 && u.i<<12 != 0) /* nan */
  11. return x;
  12. u.i &= 1ULL<<63;
  13. return u.f;
  14. }
  15. /* no integral part*/
  16. if (e < 0) {
  17. u.i &= 1ULL<<63;
  18. *iptr = u.f;
  19. return x;
  20. }
  21. mask = -1ULL>>12>>e;
  22. if ((u.i & mask) == 0) {
  23. *iptr = x;
  24. u.i &= 1ULL<<63;
  25. return u.f;
  26. }
  27. u.i &= ~mask;
  28. *iptr = u.f;
  29. return x - u.f;
  30. }