math.cpp 4.4 KB

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