remainderf.c 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. /* origin: FreeBSD /usr/src/lib/msun/src/e_remainderf.c */
  2. /*
  3. * Conversion to float by Ian Lance Taylor, Cygnus Support, [email protected].
  4. */
  5. /*
  6. * ====================================================
  7. * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
  8. *
  9. * Developed at SunPro, a Sun Microsystems, Inc. business.
  10. * Permission to use, copy, modify, and distribute this
  11. * software is freely granted, provided that this notice
  12. * is preserved.
  13. * ====================================================
  14. */
  15. #include "libm.h"
  16. float remainderf(float x, float p)
  17. {
  18. int32_t hx,hp;
  19. uint32_t sx;
  20. float p_half;
  21. GET_FLOAT_WORD(hx, x);
  22. GET_FLOAT_WORD(hp, p);
  23. sx = hx & 0x80000000;
  24. hp &= 0x7fffffff;
  25. hx &= 0x7fffffff;
  26. /* purge off exception values */
  27. if (hp == 0 || hx >= 0x7f800000 || hp > 0x7f800000) /* p = 0, x not finite, p is NaN */
  28. return (x*p)/(x*p);
  29. if (hp <= 0x7effffff)
  30. x = fmodf(x, p + p); /* now x < 2p */
  31. if (hx - hp == 0)
  32. return 0.0f*x;
  33. x = fabsf(x);
  34. p = fabsf(p);
  35. if (hp < 0x01000000) {
  36. if (x + x > p) {
  37. x -= p;
  38. if (x + x >= p)
  39. x -= p;
  40. }
  41. } else {
  42. p_half = 0.5f*p;
  43. if (x > p_half) {
  44. x -= p;
  45. if (x >= p_half)
  46. x -= p;
  47. }
  48. }
  49. GET_FLOAT_WORD(hx, x);
  50. if ((hx & 0x7fffffff) == 0)
  51. hx = 0;
  52. SET_FLOAT_WORD(x, hx ^ sx);
  53. return x;
  54. }