math.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155
  1. /*
  2. * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
  3. * Copyright (c) 2021, Mițca Dumitru <dumitru0mitca@gmail.com>
  4. * Copyright (c) 2022, the SerenityOS developers.
  5. * Copyright (c) 2022, Leon Albrecht <leon.a@serenityos.org>
  6. *
  7. * SPDX-License-Identifier: BSD-2-Clause
  8. */
  9. #include <AK/BuiltinWrappers.h>
  10. #include <AK/ExtraMathConstants.h>
  11. #include <AK/FloatingPoint.h>
  12. #ifndef AK_ARCH_AARCH64
  13. # include <AK/FPControl.h>
  14. #endif
  15. #include <AK/Math.h>
  16. #include <AK/Platform.h>
  17. #include <AK/StdLibExtras.h>
  18. #include <LibC/assert.h>
  19. #include <fenv.h>
  20. #include <math.h>
  21. #include <stdint.h>
  22. #if defined(AK_COMPILER_CLANG)
  23. # pragma clang diagnostic push
  24. # pragma clang diagnostic ignored "-Wdouble-promotion"
  25. #endif
  26. template<size_t>
  27. constexpr double e_to_power();
  28. template<>
  29. constexpr double e_to_power<0>() { return 1; }
  30. template<size_t exponent>
  31. constexpr double e_to_power() { return M_E * e_to_power<exponent - 1>(); }
  32. template<size_t>
  33. constexpr size_t factorial();
  34. template<>
  35. constexpr size_t factorial<0>() { return 1; }
  36. template<size_t value>
  37. constexpr size_t factorial() { return value * factorial<value - 1>(); }
  38. template<size_t>
  39. constexpr size_t product_even();
  40. template<>
  41. constexpr size_t product_even<2>() { return 2; }
  42. template<size_t value>
  43. constexpr size_t product_even() { return value * product_even<value - 2>(); }
  44. template<size_t>
  45. constexpr size_t product_odd();
  46. template<>
  47. constexpr size_t product_odd<1>() { return 1; }
  48. template<size_t value>
  49. constexpr size_t product_odd() { return value * product_odd<value - 2>(); }
  50. enum class RoundingMode {
  51. ToZero = FE_TOWARDZERO,
  52. Up = FE_UPWARD,
  53. Down = FE_DOWNWARD,
  54. ToEven = FE_TONEAREST
  55. };
  56. // This is much branchier than it really needs to be
  57. template<typename FloatType>
  58. static FloatType internal_to_integer(FloatType x, RoundingMode rounding_mode)
  59. {
  60. if (!isfinite(x))
  61. return x;
  62. using Extractor = FloatExtractor<decltype(x)>;
  63. Extractor extractor;
  64. extractor.d = x;
  65. auto unbiased_exponent = extractor.exponent - Extractor::exponent_bias;
  66. bool has_half_fraction = false;
  67. bool has_nonhalf_fraction = false;
  68. if (unbiased_exponent < 0) {
  69. // it was easier to special case [0..1) as it saves us from
  70. // handling subnormals, underflows, etc
  71. if (unbiased_exponent == -1) {
  72. has_half_fraction = true;
  73. }
  74. has_nonhalf_fraction = unbiased_exponent < -1 || extractor.mantissa != 0;
  75. extractor.mantissa = 0;
  76. extractor.exponent = 0;
  77. } else {
  78. if (unbiased_exponent >= Extractor::mantissa_bits)
  79. return x;
  80. auto dead_bitcount = Extractor::mantissa_bits - unbiased_exponent;
  81. auto dead_mask = (1ull << dead_bitcount) - 1;
  82. auto dead_bits = extractor.mantissa & dead_mask;
  83. extractor.mantissa &= ~dead_mask;
  84. auto nonhalf_fraction_mask = dead_mask >> 1;
  85. has_nonhalf_fraction = (dead_bits & nonhalf_fraction_mask) != 0;
  86. has_half_fraction = (dead_bits & ~nonhalf_fraction_mask) != 0;
  87. }
  88. bool should_round = false;
  89. switch (rounding_mode) {
  90. case RoundingMode::ToEven:
  91. should_round = has_half_fraction;
  92. break;
  93. case RoundingMode::Up:
  94. if (!extractor.sign)
  95. should_round = has_nonhalf_fraction || has_half_fraction;
  96. break;
  97. case RoundingMode::Down:
  98. if (extractor.sign)
  99. should_round = has_nonhalf_fraction || has_half_fraction;
  100. break;
  101. case RoundingMode::ToZero:
  102. break;
  103. }
  104. if (should_round) {
  105. // We could do this ourselves, but this saves us from manually
  106. // handling overflow.
  107. if (extractor.sign)
  108. extractor.d -= static_cast<FloatType>(1.0);
  109. else
  110. extractor.d += static_cast<FloatType>(1.0);
  111. }
  112. return extractor.d;
  113. }
  114. // This is much branchier than it really needs to be
  115. template<typename FloatType>
  116. static FloatType internal_nextafter(FloatType x, bool up)
  117. {
  118. if (!isfinite(x))
  119. return x;
  120. using Extractor = FloatExtractor<decltype(x)>;
  121. Extractor extractor;
  122. extractor.d = x;
  123. if (x == 0) {
  124. if (!extractor.sign) {
  125. extractor.mantissa = 1;
  126. extractor.sign = !up;
  127. return extractor.d;
  128. }
  129. if (up) {
  130. extractor.sign = false;
  131. extractor.mantissa = 1;
  132. return extractor.d;
  133. }
  134. extractor.mantissa = 1;
  135. extractor.sign = up != extractor.sign;
  136. return extractor.d;
  137. }
  138. if (up != extractor.sign) {
  139. extractor.mantissa++;
  140. if (!extractor.mantissa) {
  141. // no need to normalize the mantissa as we just hit a power
  142. // of two.
  143. extractor.exponent++;
  144. if (extractor.exponent == Extractor::exponent_max) {
  145. extractor.exponent = Extractor::exponent_max - 1;
  146. extractor.mantissa = Extractor::mantissa_max;
  147. }
  148. }
  149. return extractor.d;
  150. }
  151. if (!extractor.mantissa) {
  152. if (extractor.exponent) {
  153. extractor.exponent--;
  154. extractor.mantissa = Extractor::mantissa_max;
  155. } else {
  156. extractor.d = 0;
  157. }
  158. return extractor.d;
  159. }
  160. extractor.mantissa--;
  161. if (extractor.mantissa != Extractor::mantissa_max)
  162. return extractor.d;
  163. if (extractor.exponent) {
  164. extractor.exponent--;
  165. // normalize
  166. extractor.mantissa <<= 1;
  167. } else {
  168. if (extractor.sign) {
  169. // Negative infinity
  170. extractor.mantissa = 0;
  171. extractor.exponent = Extractor::exponent_max;
  172. }
  173. }
  174. return extractor.d;
  175. }
  176. template<typename FloatT>
  177. static int internal_ilogb(FloatT x) NOEXCEPT
  178. {
  179. if (x == 0)
  180. return FP_ILOGB0;
  181. if (isnan(x))
  182. return FP_ILOGNAN;
  183. if (!isfinite(x))
  184. return INT_MAX;
  185. using Extractor = FloatExtractor<FloatT>;
  186. Extractor extractor;
  187. extractor.d = x;
  188. return (int)extractor.exponent - Extractor::exponent_bias;
  189. }
  190. template<typename FloatT>
  191. static FloatT internal_modf(FloatT x, FloatT* intpart) NOEXCEPT
  192. {
  193. FloatT integer_part = internal_to_integer(x, RoundingMode::ToZero);
  194. *intpart = integer_part;
  195. auto fraction = x - integer_part;
  196. if (signbit(fraction) != signbit(x))
  197. fraction = -fraction;
  198. return fraction;
  199. }
  200. template<typename FloatT>
  201. static FloatT internal_scalbn(FloatT x, int exponent) NOEXCEPT
  202. {
  203. if (x == 0 || !isfinite(x) || isnan(x) || exponent == 0)
  204. return x;
  205. using Extractor = FloatExtractor<FloatT>;
  206. Extractor extractor;
  207. extractor.d = x;
  208. if (extractor.exponent != 0) {
  209. extractor.exponent = clamp((int)extractor.exponent + exponent, 0, (int)Extractor::exponent_max);
  210. return extractor.d;
  211. }
  212. unsigned leading_mantissa_zeroes = extractor.mantissa == 0 ? 32 : count_leading_zeroes(extractor.mantissa);
  213. int shift = min((int)leading_mantissa_zeroes, exponent);
  214. exponent = max(exponent - shift, 0);
  215. extractor.exponent <<= shift;
  216. extractor.exponent = exponent + 1;
  217. return extractor.d;
  218. }
  219. template<typename FloatT>
  220. static FloatT internal_copysign(FloatT x, FloatT y) NOEXCEPT
  221. {
  222. using Extractor = FloatExtractor<FloatT>;
  223. Extractor ex, ey;
  224. ex.d = x;
  225. ey.d = y;
  226. ex.sign = ey.sign;
  227. return ex.d;
  228. }
  229. template<typename FloatT>
  230. static FloatT internal_gamma(FloatT x) NOEXCEPT
  231. {
  232. if (isnan(x))
  233. return (FloatT)NAN;
  234. if (x == (FloatT)0.0)
  235. return signbit(x) ? (FloatT)-INFINITY : (FloatT)INFINITY;
  236. if (x < (FloatT)0 && (rintl(x) == x || isinf(x)))
  237. return (FloatT)NAN;
  238. if (isinf(x))
  239. return (FloatT)INFINITY;
  240. using Extractor = FloatExtractor<FloatT>;
  241. // These constants were obtained through use of WolframAlpha
  242. constexpr long long max_integer_whose_factorial_fits = (Extractor::mantissa_bits == FloatExtractor<long double>::mantissa_bits ? 20 : (Extractor::mantissa_bits == FloatExtractor<double>::mantissa_bits ? 18 : (Extractor::mantissa_bits == FloatExtractor<float>::mantissa_bits ? 10 : 0)));
  243. static_assert(max_integer_whose_factorial_fits != 0, "internal_gamma needs to be aware of the integer factorial that fits in this floating point type.");
  244. if ((int)x == x && x <= max_integer_whose_factorial_fits + 1) {
  245. long long result = 1;
  246. for (long long cursor = 2; cursor < (long long)x; cursor++)
  247. result *= cursor;
  248. return (FloatT)result;
  249. }
  250. // Stirling approximation
  251. return sqrtl(2.0 * M_PIl / static_cast<long double>(x)) * powl(static_cast<long double>(x) / M_El, static_cast<long double>(x));
  252. }
  253. extern "C" {
  254. float nanf(char const* s) NOEXCEPT
  255. {
  256. return __builtin_nanf(s);
  257. }
  258. double nan(char const* s) NOEXCEPT
  259. {
  260. return __builtin_nan(s);
  261. }
  262. long double nanl(char const* s) NOEXCEPT
  263. {
  264. return __builtin_nanl(s);
  265. }
  266. #define MAKE_AK_BACKED1(name) \
  267. long double name##l(long double arg) NOEXCEPT \
  268. { \
  269. return AK::name<long double>(arg); \
  270. } \
  271. double name(double arg) NOEXCEPT \
  272. { \
  273. return AK::name<double>(arg); \
  274. } \
  275. float name##f(float arg) NOEXCEPT \
  276. { \
  277. return AK::name<float>(arg); \
  278. }
  279. #define MAKE_AK_BACKED2(name) \
  280. long double name##l(long double arg1, long double arg2) NOEXCEPT \
  281. { \
  282. return AK::name<long double>(arg1, arg2); \
  283. } \
  284. double name(double arg1, double arg2) NOEXCEPT \
  285. { \
  286. return AK::name<double>(arg1, arg2); \
  287. } \
  288. float name##f(float arg1, float arg2) NOEXCEPT \
  289. { \
  290. return AK::name<float>(arg1, arg2); \
  291. }
  292. MAKE_AK_BACKED1(sin);
  293. MAKE_AK_BACKED1(cos);
  294. MAKE_AK_BACKED1(tan);
  295. MAKE_AK_BACKED1(asin);
  296. MAKE_AK_BACKED1(acos);
  297. MAKE_AK_BACKED1(atan);
  298. MAKE_AK_BACKED1(sinh);
  299. MAKE_AK_BACKED1(cosh);
  300. MAKE_AK_BACKED1(tanh);
  301. MAKE_AK_BACKED1(asinh);
  302. MAKE_AK_BACKED1(acosh);
  303. MAKE_AK_BACKED1(atanh);
  304. MAKE_AK_BACKED1(sqrt);
  305. MAKE_AK_BACKED1(cbrt);
  306. MAKE_AK_BACKED1(log);
  307. MAKE_AK_BACKED1(log2);
  308. MAKE_AK_BACKED1(log10);
  309. MAKE_AK_BACKED1(exp);
  310. MAKE_AK_BACKED1(exp2);
  311. MAKE_AK_BACKED1(fabs);
  312. MAKE_AK_BACKED2(atan2);
  313. MAKE_AK_BACKED2(hypot);
  314. MAKE_AK_BACKED2(fmod);
  315. MAKE_AK_BACKED2(pow);
  316. MAKE_AK_BACKED2(remainder);
  317. long double truncl(long double x) NOEXCEPT
  318. {
  319. #ifndef AK_ARCH_AARCH64
  320. if (fabsl(x) < LONG_LONG_MAX) {
  321. // This is 1.6 times faster than the implementation using the "internal_to_integer"
  322. // helper (on x86_64)
  323. // https://quick-bench.com/q/xBmxuY8am9qibSYVna90Y6PIvqA
  324. u64 temp;
  325. asm(
  326. "fisttpq %[temp]\n"
  327. "fildq %[temp]"
  328. : "+t"(x)
  329. : [temp] "m"(temp));
  330. return x;
  331. }
  332. #endif
  333. return internal_to_integer(x, RoundingMode::ToZero);
  334. }
  335. double trunc(double x) NOEXCEPT
  336. {
  337. #ifndef AK_ARCH_AARCH64
  338. if (fabs(x) < LONG_LONG_MAX) {
  339. u64 temp;
  340. asm(
  341. "fisttpq %[temp]\n"
  342. "fildq %[temp]"
  343. : "+t"(x)
  344. : [temp] "m"(temp));
  345. return x;
  346. }
  347. #endif
  348. return internal_to_integer(x, RoundingMode::ToZero);
  349. }
  350. float truncf(float x) NOEXCEPT
  351. {
  352. #ifndef AK_ARCH_AARCH64
  353. if (fabsf(x) < LONG_LONG_MAX) {
  354. u64 temp;
  355. asm(
  356. "fisttpq %[temp]\n"
  357. "fildq %[temp]"
  358. : "+t"(x)
  359. : [temp] "m"(temp));
  360. return x;
  361. }
  362. #endif
  363. return internal_to_integer(x, RoundingMode::ToZero);
  364. }
  365. long double rintl(long double value)
  366. {
  367. #ifdef AK_ARCH_AARCH64
  368. (void)value;
  369. TODO_AARCH64();
  370. #else
  371. long double res;
  372. asm(
  373. "frndint\n"
  374. : "=t"(res)
  375. : "0"(value));
  376. return res;
  377. #endif
  378. }
  379. double rint(double value)
  380. {
  381. #ifdef AK_ARCH_AARCH64
  382. (void)value;
  383. TODO_AARCH64();
  384. #else
  385. double res;
  386. asm(
  387. "frndint\n"
  388. : "=t"(res)
  389. : "0"(value));
  390. return res;
  391. #endif
  392. }
  393. float rintf(float value)
  394. {
  395. #ifdef AK_ARCH_AARCH64
  396. (void)value;
  397. TODO_AARCH64();
  398. #else
  399. float res;
  400. asm(
  401. "frndint\n"
  402. : "=t"(res)
  403. : "0"(value));
  404. return res;
  405. #endif
  406. }
  407. long lrintl(long double value)
  408. {
  409. #ifdef AK_ARCH_AARCH64
  410. (void)value;
  411. TODO_AARCH64();
  412. #else
  413. long res;
  414. asm(
  415. "fistpl %0\n"
  416. : "+m"(res)
  417. : "t"(value)
  418. : "st");
  419. return res;
  420. #endif
  421. }
  422. long lrint(double value)
  423. {
  424. #ifdef AK_ARCH_AARCH64
  425. (void)value;
  426. TODO_AARCH64();
  427. #else
  428. long res;
  429. asm(
  430. "fistpl %0\n"
  431. : "+m"(res)
  432. : "t"(value)
  433. : "st");
  434. return res;
  435. #endif
  436. }
  437. long lrintf(float value)
  438. {
  439. #ifdef AK_ARCH_AARCH64
  440. (void)value;
  441. TODO_AARCH64();
  442. #else
  443. long res;
  444. asm(
  445. "fistpl %0\n"
  446. : "+m"(res)
  447. : "t"(value)
  448. : "st");
  449. return res;
  450. #endif
  451. }
  452. long long llrintl(long double value)
  453. {
  454. #ifdef AK_ARCH_AARCH64
  455. (void)value;
  456. TODO_AARCH64();
  457. #else
  458. long long res;
  459. asm(
  460. "fistpq %0\n"
  461. : "+m"(res)
  462. : "t"(value)
  463. : "st");
  464. return res;
  465. #endif
  466. }
  467. long long llrint(double value)
  468. {
  469. #ifdef AK_ARCH_AARCH64
  470. (void)value;
  471. TODO_AARCH64();
  472. #else
  473. long long res;
  474. asm(
  475. "fistpq %0\n"
  476. : "+m"(res)
  477. : "t"(value)
  478. : "st");
  479. return res;
  480. #endif
  481. }
  482. long long llrintf(float value)
  483. {
  484. #ifdef AK_ARCH_AARCH64
  485. (void)value;
  486. TODO_AARCH64();
  487. #else
  488. long long res;
  489. asm(
  490. "fistpq %0\n"
  491. : "+m"(res)
  492. : "t"(value)
  493. : "st");
  494. return res;
  495. #endif
  496. }
  497. // On systems where FLT_RADIX == 2, ldexp is equivalent to scalbn
  498. long double ldexpl(long double x, int exp) NOEXCEPT
  499. {
  500. return internal_scalbn(x, exp);
  501. }
  502. double ldexp(double x, int exp) NOEXCEPT
  503. {
  504. return internal_scalbn(x, exp);
  505. }
  506. float ldexpf(float x, int exp) NOEXCEPT
  507. {
  508. return internal_scalbn(x, exp);
  509. }
  510. [[maybe_unused]] static long double ampsin(long double angle) NOEXCEPT
  511. {
  512. long double looped_angle = fmodl(M_PI + angle, M_TAU) - M_PI;
  513. long double looped_angle_squared = looped_angle * looped_angle;
  514. long double quadratic_term;
  515. if (looped_angle > 0) {
  516. quadratic_term = -looped_angle_squared;
  517. } else {
  518. quadratic_term = looped_angle_squared;
  519. }
  520. long double linear_term = M_PI * looped_angle;
  521. return quadratic_term + linear_term;
  522. }
  523. int ilogbl(long double x) NOEXCEPT
  524. {
  525. return internal_ilogb(x);
  526. }
  527. int ilogb(double x) NOEXCEPT
  528. {
  529. return internal_ilogb(x);
  530. }
  531. int ilogbf(float x) NOEXCEPT
  532. {
  533. return internal_ilogb(x);
  534. }
  535. long double logbl(long double x) NOEXCEPT
  536. {
  537. return ilogbl(x);
  538. }
  539. double logb(double x) NOEXCEPT
  540. {
  541. return ilogb(x);
  542. }
  543. float logbf(float x) NOEXCEPT
  544. {
  545. return ilogbf(x);
  546. }
  547. double frexp(double x, int* exp) NOEXCEPT
  548. {
  549. *exp = (x == 0) ? 0 : (1 + ilogb(x));
  550. return scalbn(x, -(*exp));
  551. }
  552. float frexpf(float x, int* exp) NOEXCEPT
  553. {
  554. *exp = (x == 0) ? 0 : (1 + ilogbf(x));
  555. return scalbnf(x, -(*exp));
  556. }
  557. long double frexpl(long double x, int* exp) NOEXCEPT
  558. {
  559. *exp = (x == 0) ? 0 : (1 + ilogbl(x));
  560. return scalbnl(x, -(*exp));
  561. }
  562. #if !(ARCH(X86_64))
  563. double round(double value) NOEXCEPT
  564. {
  565. return internal_to_integer(value, RoundingMode::ToEven);
  566. }
  567. float roundf(float value) NOEXCEPT
  568. {
  569. return internal_to_integer(value, RoundingMode::ToEven);
  570. }
  571. long double roundl(long double value) NOEXCEPT
  572. {
  573. return internal_to_integer(value, RoundingMode::ToEven);
  574. }
  575. long lroundf(float value) NOEXCEPT
  576. {
  577. return internal_to_integer(value, RoundingMode::ToEven);
  578. }
  579. long lround(double value) NOEXCEPT
  580. {
  581. return internal_to_integer(value, RoundingMode::ToEven);
  582. }
  583. long lroundl(long double value) NOEXCEPT
  584. {
  585. return internal_to_integer(value, RoundingMode::ToEven);
  586. }
  587. long long llroundf(float value) NOEXCEPT
  588. {
  589. return internal_to_integer(value, RoundingMode::ToEven);
  590. }
  591. long long llround(double value) NOEXCEPT
  592. {
  593. return internal_to_integer(value, RoundingMode::ToEven);
  594. }
  595. long long llroundd(long double value) NOEXCEPT
  596. {
  597. return internal_to_integer(value, RoundingMode::ToEven);
  598. }
  599. float floorf(float value) NOEXCEPT
  600. {
  601. return internal_to_integer(value, RoundingMode::Down);
  602. }
  603. double floor(double value) NOEXCEPT
  604. {
  605. return internal_to_integer(value, RoundingMode::Down);
  606. }
  607. long double floorl(long double value) NOEXCEPT
  608. {
  609. return internal_to_integer(value, RoundingMode::Down);
  610. }
  611. float ceilf(float value) NOEXCEPT
  612. {
  613. return internal_to_integer(value, RoundingMode::Up);
  614. }
  615. double ceil(double value) NOEXCEPT
  616. {
  617. return internal_to_integer(value, RoundingMode::Up);
  618. }
  619. long double ceill(long double value) NOEXCEPT
  620. {
  621. return internal_to_integer(value, RoundingMode::Up);
  622. }
  623. #else
  624. double round(double x) NOEXCEPT
  625. {
  626. // Note: This is break-tie-away-from-zero, so not the hw's understanding of
  627. // "nearest", which would be towards even.
  628. if (x == 0.)
  629. return x;
  630. if (x > 0.)
  631. return floor(x + .5);
  632. return ceil(x - .5);
  633. }
  634. float roundf(float x) NOEXCEPT
  635. {
  636. if (x == 0.f)
  637. return x;
  638. if (x > 0.f)
  639. return floorf(x + .5f);
  640. return ceilf(x - .5f);
  641. }
  642. long double roundl(long double x) NOEXCEPT
  643. {
  644. if (x == 0.L)
  645. return x;
  646. if (x > 0.L)
  647. return floorl(x + .5L);
  648. return ceill(x - .5L);
  649. }
  650. long lroundf(float value) NOEXCEPT
  651. {
  652. return static_cast<long>(roundf(value));
  653. }
  654. long lround(double value) NOEXCEPT
  655. {
  656. return static_cast<long>(round(value));
  657. }
  658. long lroundl(long double value) NOEXCEPT
  659. {
  660. return static_cast<long>(roundl(value));
  661. }
  662. long long llroundf(float value) NOEXCEPT
  663. {
  664. return static_cast<long long>(roundf(value));
  665. }
  666. long long llround(double value) NOEXCEPT
  667. {
  668. return static_cast<long long>(round(value));
  669. }
  670. long long llroundd(long double value) NOEXCEPT
  671. {
  672. return static_cast<long long>(roundl(value));
  673. }
  674. float floorf(float value) NOEXCEPT
  675. {
  676. AK::X87RoundingModeScope scope { AK::RoundingMode::DOWN };
  677. asm("frndint"
  678. : "+t"(value));
  679. return value;
  680. }
  681. double floor(double value) NOEXCEPT
  682. {
  683. AK::X87RoundingModeScope scope { AK::RoundingMode::DOWN };
  684. asm("frndint"
  685. : "+t"(value));
  686. return value;
  687. }
  688. long double floorl(long double value) NOEXCEPT
  689. {
  690. AK::X87RoundingModeScope scope { AK::RoundingMode::DOWN };
  691. asm("frndint"
  692. : "+t"(value));
  693. return value;
  694. }
  695. float ceilf(float value) NOEXCEPT
  696. {
  697. AK::X87RoundingModeScope scope { AK::RoundingMode::UP };
  698. asm("frndint"
  699. : "+t"(value));
  700. return value;
  701. }
  702. double ceil(double value) NOEXCEPT
  703. {
  704. AK::X87RoundingModeScope scope { AK::RoundingMode::UP };
  705. asm("frndint"
  706. : "+t"(value));
  707. return value;
  708. }
  709. long double ceill(long double value) NOEXCEPT
  710. {
  711. AK::X87RoundingModeScope scope { AK::RoundingMode::UP };
  712. asm("frndint"
  713. : "+t"(value));
  714. return value;
  715. }
  716. #endif
  717. long double modfl(long double x, long double* intpart) NOEXCEPT
  718. {
  719. return internal_modf(x, intpart);
  720. }
  721. double modf(double x, double* intpart) NOEXCEPT
  722. {
  723. return internal_modf(x, intpart);
  724. }
  725. float modff(float x, float* intpart) NOEXCEPT
  726. {
  727. return internal_modf(x, intpart);
  728. }
  729. double gamma(double x) NOEXCEPT
  730. {
  731. // Stirling approximation
  732. return sqrt(2.0 * M_PI / x) * pow(x / M_E, x);
  733. }
  734. long double tgammal(long double value) NOEXCEPT
  735. {
  736. return internal_gamma(value);
  737. }
  738. double tgamma(double value) NOEXCEPT
  739. {
  740. return internal_gamma(value);
  741. }
  742. float tgammaf(float value) NOEXCEPT
  743. {
  744. return internal_gamma(value);
  745. }
  746. int signgam = 0;
  747. long double lgammal(long double value) NOEXCEPT
  748. {
  749. return lgammal_r(value, &signgam);
  750. }
  751. double lgamma(double value) NOEXCEPT
  752. {
  753. return lgamma_r(value, &signgam);
  754. }
  755. float lgammaf(float value) NOEXCEPT
  756. {
  757. return lgammaf_r(value, &signgam);
  758. }
  759. long double lgammal_r(long double value, int* sign) NOEXCEPT
  760. {
  761. if (value == 1.0 || value == 2.0)
  762. return 0.0;
  763. if (isinf(value) || value == 0.0)
  764. return INFINITY;
  765. long double result = logl(internal_gamma(value));
  766. *sign = signbit(result) ? -1 : 1;
  767. return result;
  768. }
  769. double lgamma_r(double value, int* sign) NOEXCEPT
  770. {
  771. if (value == 1.0 || value == 2.0)
  772. return 0.0;
  773. if (isinf(value) || value == 0.0)
  774. return INFINITY;
  775. double result = log(internal_gamma(value));
  776. *sign = signbit(result) ? -1 : 1;
  777. return result;
  778. }
  779. float lgammaf_r(float value, int* sign) NOEXCEPT
  780. {
  781. if (value == 1.0f || value == 2.0f)
  782. return 0.0;
  783. if (isinf(value) || value == 0.0f)
  784. return INFINITY;
  785. float result = logf(internal_gamma(value));
  786. *sign = signbit(result) ? -1 : 1;
  787. return result;
  788. }
  789. long double expm1l(long double x) NOEXCEPT
  790. {
  791. return expl(x) - 1;
  792. }
  793. double expm1(double x) NOEXCEPT
  794. {
  795. return exp(x) - 1;
  796. }
  797. float expm1f(float x) NOEXCEPT
  798. {
  799. return expf(x) - 1;
  800. }
  801. long double log1pl(long double x) NOEXCEPT
  802. {
  803. return logl(1 + x);
  804. }
  805. double log1p(double x) NOEXCEPT
  806. {
  807. return log(1 + x);
  808. }
  809. float log1pf(float x) NOEXCEPT
  810. {
  811. return logf(1 + x);
  812. }
  813. long double erfl(long double x) NOEXCEPT
  814. {
  815. // algorithm taken from Abramowitz and Stegun (no. 26.2.17)
  816. long double t = 1 / (1 + 0.47047l * fabsl(x));
  817. long double poly = t * (0.3480242l + t * (-0.958798l + t * 0.7478556l));
  818. long double answer = 1 - poly * expl(-x * x);
  819. if (x < 0)
  820. return -answer;
  821. return answer;
  822. }
  823. double erf(double x) NOEXCEPT
  824. {
  825. return (double)erfl(x);
  826. }
  827. float erff(float x) NOEXCEPT
  828. {
  829. return (float)erf(x);
  830. }
  831. long double erfcl(long double x) NOEXCEPT
  832. {
  833. return 1 - erfl(x);
  834. }
  835. double erfc(double x) NOEXCEPT
  836. {
  837. return 1 - erf(x);
  838. }
  839. float erfcf(float x) NOEXCEPT
  840. {
  841. return 1 - erff(x);
  842. }
  843. double nextafter(double x, double target) NOEXCEPT
  844. {
  845. if (x == target)
  846. return target;
  847. return internal_nextafter(x, target >= x);
  848. }
  849. float nextafterf(float x, float target) NOEXCEPT
  850. {
  851. if (x == target)
  852. return target;
  853. return internal_nextafter(x, target >= x);
  854. }
  855. long double nextafterl(long double x, long double target) NOEXCEPT
  856. {
  857. return internal_nextafter(x, target >= x);
  858. }
  859. double nexttoward(double x, long double target) NOEXCEPT
  860. {
  861. if (x == target)
  862. return target;
  863. return internal_nextafter(x, target >= x);
  864. }
  865. float nexttowardf(float x, long double target) NOEXCEPT
  866. {
  867. if (x == target)
  868. return target;
  869. return internal_nextafter(x, target >= x);
  870. }
  871. long double nexttowardl(long double x, long double target) NOEXCEPT
  872. {
  873. if (x == target)
  874. return target;
  875. return internal_nextafter(x, target >= x);
  876. }
  877. float copysignf(float x, float y) NOEXCEPT
  878. {
  879. return internal_copysign(x, y);
  880. }
  881. double copysign(double x, double y) NOEXCEPT
  882. {
  883. return internal_copysign(x, y);
  884. }
  885. long double copysignl(long double x, long double y) NOEXCEPT
  886. {
  887. return internal_copysign(x, y);
  888. }
  889. float scalbnf(float x, int exponent) NOEXCEPT
  890. {
  891. return internal_scalbn(x, exponent);
  892. }
  893. double scalbn(double x, int exponent) NOEXCEPT
  894. {
  895. return internal_scalbn(x, exponent);
  896. }
  897. long double scalbnl(long double x, int exponent) NOEXCEPT
  898. {
  899. return internal_scalbn(x, exponent);
  900. }
  901. float scalbnlf(float x, long exponent) NOEXCEPT
  902. {
  903. return internal_scalbn(x, exponent);
  904. }
  905. double scalbln(double x, long exponent) NOEXCEPT
  906. {
  907. return internal_scalbn(x, exponent);
  908. }
  909. long double scalblnl(long double x, long exponent) NOEXCEPT
  910. {
  911. return internal_scalbn(x, exponent);
  912. }
  913. long double fmaxl(long double x, long double y) NOEXCEPT
  914. {
  915. if (isnan(x))
  916. return y;
  917. if (isnan(y))
  918. return x;
  919. return x > y ? x : y;
  920. }
  921. double fmax(double x, double y) NOEXCEPT
  922. {
  923. if (isnan(x))
  924. return y;
  925. if (isnan(y))
  926. return x;
  927. return x > y ? x : y;
  928. }
  929. float fmaxf(float x, float y) NOEXCEPT
  930. {
  931. if (isnan(x))
  932. return y;
  933. if (isnan(y))
  934. return x;
  935. return x > y ? x : y;
  936. }
  937. long double fminl(long double x, long double y) NOEXCEPT
  938. {
  939. if (isnan(x))
  940. return y;
  941. if (isnan(y))
  942. return x;
  943. return x < y ? x : y;
  944. }
  945. double fmin(double x, double y) NOEXCEPT
  946. {
  947. if (isnan(x))
  948. return y;
  949. if (isnan(y))
  950. return x;
  951. return x < y ? x : y;
  952. }
  953. float fminf(float x, float y) NOEXCEPT
  954. {
  955. if (isnan(x))
  956. return y;
  957. if (isnan(y))
  958. return x;
  959. return x < y ? x : y;
  960. }
  961. // https://pubs.opengroup.org/onlinepubs/9699919799/functions/fma.html
  962. long double fmal(long double x, long double y, long double z) NOEXCEPT
  963. {
  964. return (x * y) + z;
  965. }
  966. double fma(double x, double y, double z) NOEXCEPT
  967. {
  968. return (x * y) + z;
  969. }
  970. float fmaf(float x, float y, float z) NOEXCEPT
  971. {
  972. return (x * y) + z;
  973. }
  974. long double nearbyintl(long double value) NOEXCEPT
  975. {
  976. return internal_to_integer(value, RoundingMode { fegetround() });
  977. }
  978. double nearbyint(double value) NOEXCEPT
  979. {
  980. return internal_to_integer(value, RoundingMode { fegetround() });
  981. }
  982. float nearbyintf(float value) NOEXCEPT
  983. {
  984. return internal_to_integer(value, RoundingMode { fegetround() });
  985. }
  986. }
  987. #if defined(AK_COMPILER_CLANG)
  988. # pragma clang diagnostic pop
  989. #endif