frexp.c 1.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. #include <math.h>
  2. #include <errno.h>
  3. #define _RESEARCH_SOURCE
  4. #include <float.h>
  5. #define MASK 0x7ffL
  6. #define SHIFT 20
  7. #define BIAS 1022L
  8. typedef union
  9. {
  10. double d;
  11. struct
  12. {
  13. #ifdef IEEE_8087
  14. long ls;
  15. long ms;
  16. #else
  17. long ms;
  18. long ls;
  19. #endif
  20. };
  21. } Cheat;
  22. double
  23. frexp(double d, int *ep)
  24. {
  25. Cheat x;
  26. if(d == 0) {
  27. *ep = 0;
  28. return 0;
  29. }
  30. x.d = d;
  31. *ep = ((x.ms >> SHIFT) & MASK) - BIAS;
  32. x.ms &= ~(MASK << SHIFT);
  33. x.ms |= BIAS << SHIFT;
  34. return x.d;
  35. }
  36. double
  37. ldexp(double d, int e)
  38. {
  39. Cheat x;
  40. if(d == 0)
  41. return 0;
  42. x.d = d;
  43. e += (x.ms >> SHIFT) & MASK;
  44. if(e <= 0)
  45. return 0;
  46. if(e >= MASK){
  47. errno = ERANGE;
  48. if(d < 0)
  49. return -HUGE_VAL;
  50. return HUGE_VAL;
  51. }
  52. x.ms &= ~(MASK << SHIFT);
  53. x.ms |= (long)e << SHIFT;
  54. return x.d;
  55. }
  56. double
  57. modf(double d, double *ip)
  58. {
  59. double f;
  60. Cheat x;
  61. int e;
  62. if(d < 1) {
  63. if(d < 0) {
  64. f = modf(-d, ip);
  65. *ip = -*ip;
  66. return -f;
  67. }
  68. *ip = 0;
  69. return d;
  70. }
  71. x.d = d;
  72. e = ((x.ms >> SHIFT) & MASK) - BIAS;
  73. if(e <= SHIFT+1) {
  74. x.ms &= ~(0x1fffffL >> e);
  75. x.ls = 0;
  76. } else
  77. if(e <= SHIFT+33)
  78. x.ls &= ~(0x7fffffffL >> (e-SHIFT-2));
  79. *ip = x.d;
  80. return d - x.d;
  81. }