math.cpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. #include <LibC/assert.h>
  2. #include <LibM/math.h>
  3. #include <stdint.h>
  4. #include <stdlib.h>
  5. template<size_t>
  6. constexpr double e_to_power();
  7. template<>
  8. constexpr double e_to_power<0>() { return 1; }
  9. template<size_t exponent>
  10. constexpr double e_to_power() { return M_E * e_to_power<exponent - 1>(); }
  11. template<size_t>
  12. constexpr size_t factorial();
  13. template<>
  14. constexpr size_t factorial<0>() { return 1; }
  15. template<size_t value>
  16. constexpr size_t factorial() { return value * factorial<value - 1>(); }
  17. template<size_t>
  18. constexpr size_t product_even();
  19. template<>
  20. constexpr size_t product_even<2>() { return 2; }
  21. template<size_t value>
  22. constexpr size_t product_even() { return value * product_even<value - 2>(); }
  23. template<size_t>
  24. constexpr size_t product_odd();
  25. template<>
  26. constexpr size_t product_odd<1>() { return 1; }
  27. template<size_t value>
  28. constexpr size_t product_odd() { return value * product_odd<value - 2>(); }
  29. extern "C" {
  30. double trunc(double x)
  31. {
  32. return (int64_t)x;
  33. }
  34. double cos(double angle)
  35. {
  36. return sin(angle + M_PI_2);
  37. }
  38. // This can also be done with a taylor expansion, but for
  39. // now this works pretty well (and doesn't mess anything up
  40. // in quake in particular, which is very Floating-Point precision
  41. // heavy)
  42. double sin(double angle)
  43. {
  44. double ret = 0.0;
  45. __asm__(
  46. "fsin"
  47. : "=t"(ret)
  48. : "0"(angle));
  49. return ret;
  50. }
  51. double pow(double x, double y)
  52. {
  53. (void)x;
  54. (void)y;
  55. ASSERT_NOT_REACHED();
  56. return 0;
  57. }
  58. double ldexp(double, int exp)
  59. {
  60. (void)exp;
  61. ASSERT_NOT_REACHED();
  62. return 0;
  63. }
  64. double tanh(double x)
  65. {
  66. if (x > 0) {
  67. double exponentiated = exp(2 * x);
  68. return (exponentiated - 1) / (exponentiated + 1);
  69. }
  70. double plusX = exp(x);
  71. double minusX = 1 / plusX;
  72. return (plusX - minusX) / (plusX + minusX);
  73. }
  74. double tan(double angle)
  75. {
  76. return ampsin(angle) / ampsin(M_PI_2 + angle);
  77. }
  78. double sqrt(double x)
  79. {
  80. double res;
  81. __asm__("fsqrt"
  82. : "=t"(res)
  83. : "0"(x));
  84. return res;
  85. }
  86. double sinh(double x)
  87. {
  88. double exponentiated = exp(x);
  89. if (x > 0)
  90. return (exponentiated * exponentiated - 1) / 2 / exponentiated;
  91. return (exponentiated - 1 / exponentiated) / 2;
  92. }
  93. double log10(double x)
  94. {
  95. return log(x) / M_LN10;
  96. }
  97. double log(double x)
  98. {
  99. if (x < 0)
  100. return __builtin_nan("");
  101. if (x == 0)
  102. return -__builtin_huge_val();
  103. double y = 1 + 2 * (x - 1) / (x + 1);
  104. double exponentiated = exp(y);
  105. y = y + 2 * (x - exponentiated) / (x + exponentiated);
  106. exponentiated = exp(y);
  107. y = y + 2 * (x - exponentiated) / (x + exponentiated);
  108. exponentiated = exp(y);
  109. return y + 2 * (x - exponentiated) / (x + exponentiated);
  110. }
  111. double fmod(double index, double period)
  112. {
  113. return index - trunc(index / period) * period;
  114. }
  115. double exp(double exponent)
  116. {
  117. double result = 1;
  118. if (exponent >= 1) {
  119. size_t integer_part = (size_t)exponent;
  120. if (integer_part & 1)
  121. result *= e_to_power<1>();
  122. if (integer_part & 2)
  123. result *= e_to_power<2>();
  124. if (integer_part > 3) {
  125. if (integer_part & 4)
  126. result *= e_to_power<4>();
  127. if (integer_part & 8)
  128. result *= e_to_power<8>();
  129. if (integer_part & 16)
  130. result *= e_to_power<16>();
  131. if (integer_part & 32)
  132. result *= e_to_power<32>();
  133. if (integer_part >= 64)
  134. return __builtin_huge_val();
  135. }
  136. exponent -= integer_part;
  137. } else if (exponent < 0)
  138. return 1 / exp(-exponent);
  139. double taylor_series_result = 1 + exponent;
  140. double taylor_series_numerator = exponent * exponent;
  141. taylor_series_result += taylor_series_numerator / factorial<2>();
  142. taylor_series_numerator *= exponent;
  143. taylor_series_result += taylor_series_numerator / factorial<3>();
  144. taylor_series_numerator *= exponent;
  145. taylor_series_result += taylor_series_numerator / factorial<4>();
  146. taylor_series_numerator *= exponent;
  147. taylor_series_result += taylor_series_numerator / factorial<5>();
  148. return result * taylor_series_result;
  149. }
  150. double cosh(double x)
  151. {
  152. double exponentiated = exp(-x);
  153. if (x < 0)
  154. return (1 + exponentiated * exponentiated) / 2 / exponentiated;
  155. return (1 / exponentiated + exponentiated) / 2;
  156. }
  157. double atan2(double y, double x)
  158. {
  159. if (x > 0)
  160. return atan(y / x);
  161. if (x == 0) {
  162. if (y > 0)
  163. return M_PI_2;
  164. if (y < 0)
  165. return -M_PI_2;
  166. return 0;
  167. }
  168. if (y >= 0)
  169. return atan(y / x) + M_PI;
  170. return atan(y / x) - M_PI;
  171. }
  172. double atan(double x)
  173. {
  174. if (x < 0)
  175. return -atan(-x);
  176. if (x > 1)
  177. return M_PI_2 - atan(1 / x);
  178. double squared = x * x;
  179. return x / (1 + 1 * 1 * squared / (3 + 2 * 2 * squared / (5 + 3 * 3 * squared / (7 + 4 * 4 * squared / (9 + 5 * 5 * squared / (11 + 6 * 6 * squared / (13 + 7 * 7 * squared)))))));
  180. }
  181. double asin(double x)
  182. {
  183. if (x > 1 || x < -1)
  184. return __builtin_nan("");
  185. if (x > 0.5 || x < -0.5)
  186. return 2 * atan(x / (1 + sqrt(1 - x * x)));
  187. double squared = x * x;
  188. double value = x;
  189. double i = x * squared;
  190. value += i * product_odd<1>() / product_even<2>() / 3;
  191. i *= squared;
  192. value += i * product_odd<3>() / product_even<4>() / 5;
  193. i *= squared;
  194. value += i * product_odd<5>() / product_even<6>() / 7;
  195. i *= squared;
  196. value += i * product_odd<7>() / product_even<8>() / 9;
  197. i *= squared;
  198. value += i * product_odd<9>() / product_even<10>() / 11;
  199. i *= squared;
  200. value += i * product_odd<11>() / product_even<12>() / 13;
  201. return value;
  202. }
  203. double acos(double x)
  204. {
  205. return M_PI_2 - asin(x);
  206. }
  207. double fabs(double value)
  208. {
  209. return value < 0 ? -value : value;
  210. }
  211. double log2(double x)
  212. {
  213. return log(x) / M_LN2;
  214. }
  215. float log2f(float x)
  216. {
  217. return log2(x);
  218. }
  219. long double log2l(long double x)
  220. {
  221. return log2(x);
  222. }
  223. double frexp(double, int*)
  224. {
  225. ASSERT_NOT_REACHED();
  226. return 0;
  227. }
  228. float frexpf(float, int*)
  229. {
  230. ASSERT_NOT_REACHED();
  231. return 0;
  232. }
  233. long double frexpl(long double, int*)
  234. {
  235. ASSERT_NOT_REACHED();
  236. return 0;
  237. }
  238. float roundf(float value)
  239. {
  240. // FIXME: Please fix me. I am naive.
  241. if (value >= 0.0f)
  242. return (float)(int)(value + 0.5f);
  243. return (float)(int)(value - 0.5f);
  244. }
  245. float ceilf(float value)
  246. {
  247. // FIXME: Please fix me. I am naive.
  248. int as_int = (int)value;
  249. if (value == (float)as_int) {
  250. return (float)as_int;
  251. }
  252. return as_int + 1;
  253. }
  254. }