frexp-spim.c 1.0 KB

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