math.cpp 25 KB

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