math.cpp 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  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 ampsin(double angle)
  75. {
  76. double looped_angle = fmod(M_PI + angle, M_TAU) - M_PI;
  77. double looped_angle_squared = looped_angle * looped_angle;
  78. double quadratic_term;
  79. if (looped_angle > 0) {
  80. quadratic_term = -looped_angle_squared;
  81. } else {
  82. quadratic_term = looped_angle_squared;
  83. }
  84. double linear_term = M_PI * looped_angle;
  85. return quadratic_term + linear_term;
  86. }
  87. double tan(double angle)
  88. {
  89. return ampsin(angle) / ampsin(M_PI_2 + angle);
  90. }
  91. double sqrt(double x)
  92. {
  93. double res;
  94. __asm__("fsqrt"
  95. : "=t"(res)
  96. : "0"(x));
  97. return res;
  98. }
  99. double sinh(double x)
  100. {
  101. double exponentiated = exp(x);
  102. if (x > 0)
  103. return (exponentiated * exponentiated - 1) / 2 / exponentiated;
  104. return (exponentiated - 1 / exponentiated) / 2;
  105. }
  106. double log10(double x)
  107. {
  108. return log(x) / M_LN10;
  109. }
  110. double log(double x)
  111. {
  112. if (x < 0)
  113. return __builtin_nan("");
  114. if (x == 0)
  115. return -__builtin_huge_val();
  116. double y = 1 + 2 * (x - 1) / (x + 1);
  117. double exponentiated = exp(y);
  118. y = y + 2 * (x - exponentiated) / (x + exponentiated);
  119. exponentiated = exp(y);
  120. y = y + 2 * (x - exponentiated) / (x + exponentiated);
  121. exponentiated = exp(y);
  122. return y + 2 * (x - exponentiated) / (x + exponentiated);
  123. }
  124. double fmod(double index, double period)
  125. {
  126. return index - trunc(index / period) * period;
  127. }
  128. double exp(double exponent)
  129. {
  130. double result = 1;
  131. if (exponent >= 1) {
  132. size_t integer_part = (size_t)exponent;
  133. if (integer_part & 1)
  134. result *= e_to_power<1>();
  135. if (integer_part & 2)
  136. result *= e_to_power<2>();
  137. if (integer_part > 3) {
  138. if (integer_part & 4)
  139. result *= e_to_power<4>();
  140. if (integer_part & 8)
  141. result *= e_to_power<8>();
  142. if (integer_part & 16)
  143. result *= e_to_power<16>();
  144. if (integer_part & 32)
  145. result *= e_to_power<32>();
  146. if (integer_part >= 64)
  147. return __builtin_huge_val();
  148. }
  149. exponent -= integer_part;
  150. } else if (exponent < 0)
  151. return 1 / exp(-exponent);
  152. double taylor_series_result = 1 + exponent;
  153. double taylor_series_numerator = exponent * exponent;
  154. taylor_series_result += taylor_series_numerator / factorial<2>();
  155. taylor_series_numerator *= exponent;
  156. taylor_series_result += taylor_series_numerator / factorial<3>();
  157. taylor_series_numerator *= exponent;
  158. taylor_series_result += taylor_series_numerator / factorial<4>();
  159. taylor_series_numerator *= exponent;
  160. taylor_series_result += taylor_series_numerator / factorial<5>();
  161. return result * taylor_series_result;
  162. }
  163. double cosh(double x)
  164. {
  165. double exponentiated = exp(-x);
  166. if (x < 0)
  167. return (1 + exponentiated * exponentiated) / 2 / exponentiated;
  168. return (1 / exponentiated + exponentiated) / 2;
  169. }
  170. double atan2(double y, double x)
  171. {
  172. if (x > 0)
  173. return atan(y / x);
  174. if (x == 0) {
  175. if (y > 0)
  176. return M_PI_2;
  177. if (y < 0)
  178. return -M_PI_2;
  179. return 0;
  180. }
  181. if (y >= 0)
  182. return atan(y / x) + M_PI;
  183. return atan(y / x) - M_PI;
  184. }
  185. double atan(double x)
  186. {
  187. if (x < 0)
  188. return -atan(-x);
  189. if (x > 1)
  190. return M_PI_2 - atan(1 / x);
  191. double squared = x * x;
  192. 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)))))));
  193. }
  194. double asin(double x)
  195. {
  196. if (x > 1 || x < -1)
  197. return __builtin_nan("");
  198. if (x > 0.5 || x < -0.5)
  199. return 2 * atan(x / (1 + sqrt(1 - x * x)));
  200. double squared = x * x;
  201. double value = x;
  202. double i = x * squared;
  203. value += i * product_odd<1>() / product_even<2>() / 3;
  204. i *= squared;
  205. value += i * product_odd<3>() / product_even<4>() / 5;
  206. i *= squared;
  207. value += i * product_odd<5>() / product_even<6>() / 7;
  208. i *= squared;
  209. value += i * product_odd<7>() / product_even<8>() / 9;
  210. i *= squared;
  211. value += i * product_odd<9>() / product_even<10>() / 11;
  212. i *= squared;
  213. value += i * product_odd<11>() / product_even<12>() / 13;
  214. return value;
  215. }
  216. double acos(double x)
  217. {
  218. return M_PI_2 - asin(x);
  219. }
  220. double fabs(double value)
  221. {
  222. return value < 0 ? -value : value;
  223. }
  224. double log2(double x)
  225. {
  226. return log(x) / M_LN2;
  227. }
  228. float log2f(float x)
  229. {
  230. return log2(x);
  231. }
  232. long double log2l(long double x)
  233. {
  234. return log2(x);
  235. }
  236. double frexp(double, int*)
  237. {
  238. ASSERT_NOT_REACHED();
  239. return 0;
  240. }
  241. float frexpf(float, int*)
  242. {
  243. ASSERT_NOT_REACHED();
  244. return 0;
  245. }
  246. long double frexpl(long double, int*)
  247. {
  248. ASSERT_NOT_REACHED();
  249. return 0;
  250. }
  251. float roundf(float value)
  252. {
  253. // FIXME: Please fix me. I am naive.
  254. if (value >= 0.0f)
  255. return (float)(int)(value + 0.5f);
  256. return (float)(int)(value - 0.5f);
  257. }
  258. float ceilf(float value)
  259. {
  260. // FIXME: Please fix me. I am naive.
  261. int as_int = (int)value;
  262. if (value == (float)as_int) {
  263. return (float)as_int;
  264. }
  265. return as_int + 1;
  266. }
  267. double modf(double x, double* intpart)
  268. {
  269. *intpart = (double)((int)(x));
  270. return x - (int)x;
  271. }
  272. }