math.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #include <LibC/assert.h>
  2. #include <LibM/math.h>
  3. #include <stdint.h>
  4. #include <stdlib.h>
  5. template<size_t> constexpr double e_to_power();
  6. template<> constexpr double e_to_power<0>() { return 1; }
  7. template<size_t exponent> constexpr double e_to_power() { return M_E * e_to_power<exponent - 1>(); }
  8. template<size_t> constexpr size_t factorial();
  9. template<> constexpr size_t factorial<0>() { return 1; }
  10. template<size_t value> constexpr size_t factorial() { return value * factorial<value - 1>(); }
  11. extern "C" {
  12. double trunc(double x)
  13. {
  14. return (int64_t)x;
  15. }
  16. double cos(double angle)
  17. {
  18. return sin(angle + M_PI_2);
  19. }
  20. double ampsin(double angle)
  21. {
  22. double looped_angle = fmod(M_PI + angle, M_TAU) - M_PI;
  23. double looped_angle_squared = looped_angle * looped_angle;
  24. double quadratic_term;
  25. if (looped_angle > 0) {
  26. quadratic_term = -looped_angle_squared;
  27. } else {
  28. quadratic_term = looped_angle_squared;
  29. }
  30. double linear_term = M_PI * looped_angle;
  31. return quadratic_term + linear_term;
  32. }
  33. double sin(double angle)
  34. {
  35. double vertical_scaling = M_PI_2 * M_PI_2;
  36. return ampsin(angle) / vertical_scaling;
  37. }
  38. double pow(double x, double y)
  39. {
  40. (void)x;
  41. (void)y;
  42. ASSERT_NOT_REACHED();
  43. return 0;
  44. }
  45. double ldexp(double, int exp)
  46. {
  47. (void)exp;
  48. ASSERT_NOT_REACHED();
  49. return 0;
  50. }
  51. double tanh(double x)
  52. {
  53. if (x > 0) {
  54. double exponentiated = exp(2 * x);
  55. return (exponentiated - 1) / (exponentiated + 1);
  56. }
  57. double plusX = exp(x);
  58. double minusX = exp(-x);
  59. return (plusX - minusX) / (plusX + minusX);
  60. }
  61. double tan(double angle)
  62. {
  63. return ampsin(angle) / ampsin(M_PI_2 + angle);
  64. }
  65. double sqrt(double x)
  66. {
  67. double res;
  68. __asm__("fsqrt" : "=t"(res) : "0"(x));
  69. return res;
  70. }
  71. double sinh(double x)
  72. {
  73. if (x > 0) {
  74. double exponentiated = exp(x);
  75. return (exponentiated * exponentiated - 1) / 2 / exponentiated;
  76. }
  77. return (exp(x) - exp(-x)) / 2;
  78. }
  79. double log10(double)
  80. {
  81. ASSERT_NOT_REACHED();
  82. return 0;
  83. }
  84. double log(double)
  85. {
  86. ASSERT_NOT_REACHED();
  87. return 0;
  88. }
  89. double fmod(double index, double period)
  90. {
  91. return index - trunc(index / period) * period;
  92. }
  93. double exp(double exponent)
  94. {
  95. double result = 1;
  96. if (exponent >= 1) {
  97. size_t integer_part = (size_t)exponent;
  98. if (integer_part & 1) result *= e_to_power<1>();
  99. if (integer_part & 2) result *= e_to_power<2>();
  100. if (integer_part > 3) {
  101. if (integer_part & 4) result *= e_to_power<4>();
  102. if (integer_part & 8) result *= e_to_power<8>();
  103. if (integer_part & 16) result *= e_to_power<16>();
  104. if (integer_part & 32) result *= e_to_power<32>();
  105. if (integer_part >= 64) return __builtin_huge_val();
  106. }
  107. exponent -= integer_part;
  108. } else if (exponent < 0)
  109. return 1 / exp(-exponent);
  110. double taylor_series_result = 1 + exponent;
  111. double taylor_series_numerator = exponent * exponent;
  112. taylor_series_result += taylor_series_numerator / factorial<2>();
  113. taylor_series_numerator *= exponent;
  114. taylor_series_result += taylor_series_numerator / factorial<3>();
  115. taylor_series_numerator *= exponent;
  116. taylor_series_result += taylor_series_numerator / factorial<4>();
  117. taylor_series_numerator *= exponent;
  118. taylor_series_result += taylor_series_numerator / factorial<5>();
  119. return result * taylor_series_result;
  120. }
  121. double cosh(double x)
  122. {
  123. if (x < 0) {
  124. double exponentiated = exp(-x);
  125. return (1 + exponentiated * exponentiated) / 2 / exponentiated;
  126. }
  127. return (exp(x) + exp(-x)) / 2;
  128. }
  129. double atan2(double, double)
  130. {
  131. ASSERT_NOT_REACHED();
  132. return 0;
  133. }
  134. double atan(double)
  135. {
  136. ASSERT_NOT_REACHED();
  137. return 0;
  138. }
  139. double asin(double)
  140. {
  141. ASSERT_NOT_REACHED();
  142. return 0;
  143. }
  144. double acos(double)
  145. {
  146. ASSERT_NOT_REACHED();
  147. return 0;
  148. }
  149. double fabs(double value)
  150. {
  151. return value < 0 ? -value : value;
  152. }
  153. double log2(double)
  154. {
  155. ASSERT_NOT_REACHED();
  156. return 0;
  157. }
  158. float log2f(float)
  159. {
  160. ASSERT_NOT_REACHED();
  161. return 0;
  162. }
  163. long double log2l(long double)
  164. {
  165. ASSERT_NOT_REACHED();
  166. return 0;
  167. }
  168. double frexp(double, int*)
  169. {
  170. ASSERT_NOT_REACHED();
  171. return 0;
  172. }
  173. float frexpf(float, int*)
  174. {
  175. ASSERT_NOT_REACHED();
  176. return 0;
  177. }
  178. long double frexpl(long double, int*)
  179. {
  180. ASSERT_NOT_REACHED();
  181. return 0;
  182. }
  183. }