math.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #include <stdint.h>
  2. #include <float.h>
  3. #include <math.h>
  4. #define FORCE_EVAL(x) \
  5. do { \
  6. if(sizeof(x) == sizeof(float)) { \
  7. volatile float __x; \
  8. __x = (x); \
  9. (void)__x; \
  10. } else if(sizeof(x) == sizeof(double)) { \
  11. volatile double __x; \
  12. __x = (x); \
  13. (void)__x; \
  14. } else { \
  15. volatile long double __x; \
  16. __x = (x); \
  17. (void)__x; \
  18. } \
  19. } while(0)
  20. float floorf(float x) {
  21. union {
  22. float f;
  23. uint32_t i;
  24. } u = {x};
  25. int e = (int)(u.i >> 23 & 0xff) - 0x7f;
  26. uint32_t m;
  27. if(e >= 23) return x;
  28. if(e >= 0) {
  29. m = 0x007fffff >> e;
  30. if((u.i & m) == 0) return x;
  31. FORCE_EVAL(x + 0x1p120f);
  32. if(u.i >> 31) u.i += m;
  33. u.i &= ~m;
  34. } else {
  35. FORCE_EVAL(x + 0x1p120f);
  36. if(u.i >> 31 == 0)
  37. u.i = 0;
  38. else if(u.i << 1)
  39. u.f = -1.0;
  40. }
  41. return u.f;
  42. }
  43. float fmodf(float x, float y) {
  44. union {
  45. float f;
  46. uint32_t i;
  47. } ux = {x}, uy = {y};
  48. int ex = ux.i >> 23 & 0xff;
  49. int ey = uy.i >> 23 & 0xff;
  50. uint32_t sx = ux.i & 0x80000000;
  51. uint32_t i;
  52. uint32_t uxi = ux.i;
  53. if(uy.i << 1 == 0 || isnan(y) || ex == 0xff) return (x * y) / (x * y);
  54. if(uxi << 1 <= uy.i << 1) {
  55. if(uxi << 1 == uy.i << 1) return 0 * x;
  56. return x;
  57. }
  58. /* normalize x and y */
  59. if(!ex) {
  60. for(i = uxi << 9; i >> 31 == 0; ex--, i <<= 1)
  61. ;
  62. uxi <<= -ex + 1;
  63. } else {
  64. uxi &= -1U >> 9;
  65. uxi |= 1U << 23;
  66. }
  67. if(!ey) {
  68. for(i = uy.i << 9; i >> 31 == 0; ey--, i <<= 1)
  69. ;
  70. uy.i <<= -ey + 1;
  71. } else {
  72. uy.i &= -1U >> 9;
  73. uy.i |= 1U << 23;
  74. }
  75. /* x mod y */
  76. for(; ex > ey; ex--) {
  77. i = uxi - uy.i;
  78. if(i >> 31 == 0) {
  79. if(i == 0) return 0 * x;
  80. uxi = i;
  81. }
  82. uxi <<= 1;
  83. }
  84. i = uxi - uy.i;
  85. if(i >> 31 == 0) {
  86. if(i == 0) return 0 * x;
  87. uxi = i;
  88. }
  89. for(; uxi >> 23 == 0; uxi <<= 1, ex--)
  90. ;
  91. /* scale result up */
  92. if(ex > 0) {
  93. uxi -= 1U << 23;
  94. uxi |= (uint32_t)ex << 23;
  95. } else {
  96. uxi >>= -ex + 1;
  97. }
  98. uxi |= sx;
  99. ux.i = uxi;
  100. return ux.f;
  101. }
  102. float nearbyintf(float x) {
  103. union {
  104. float f;
  105. uint32_t i;
  106. } u = {x};
  107. int e = u.i >> 23 & 0xff;
  108. int s = u.i >> 31;
  109. float_t y;
  110. if(e >= 0x7f + 23) return x;
  111. if(s)
  112. y = x - 0x1p23f + 0x1p23f;
  113. else
  114. y = x + 0x1p23f - 0x1p23f;
  115. if(y == 0) return s ? -0.0f : 0.0f;
  116. return y;
  117. }
  118. //
  119. // __aebi_x2x functions are just here to prevent compiler warnings
  120. //
  121. double __aeabi_i2d(int x) {
  122. return (double)x;
  123. }
  124. float __aeabi_d2f(double x) {
  125. return (float)x;
  126. }
  127. double __aeabi_f2d(float x) {
  128. return (double)x;
  129. }