diff options
author | Andreas Kling <kling@serenityos.org> | 2021-01-12 12:17:30 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-01-12 12:17:46 +0100 |
commit | 13d7c09125f8eec703d0a43a9a87fc8aa08f7319 (patch) | |
tree | 70fd643c429cea5c1f9362c2674511d17a53f3b5 /Userland/Libraries/LibM | |
parent | dc28c07fa526841e05e16161c74a6c23984f1dd5 (diff) | |
download | serenity-13d7c09125f8eec703d0a43a9a87fc8aa08f7319.zip |
Libraries: Move to Userland/Libraries/
Diffstat (limited to 'Userland/Libraries/LibM')
-rw-r--r-- | Userland/Libraries/LibM/CMakeLists.txt | 10 | ||||
-rw-r--r-- | Userland/Libraries/LibM/TestMath.cpp | 114 | ||||
-rw-r--r-- | Userland/Libraries/LibM/math.cpp | 566 | ||||
-rw-r--r-- | Userland/Libraries/LibM/math.h | 137 |
4 files changed, 827 insertions, 0 deletions
diff --git a/Userland/Libraries/LibM/CMakeLists.txt b/Userland/Libraries/LibM/CMakeLists.txt new file mode 100644 index 0000000000..bdb9baf78a --- /dev/null +++ b/Userland/Libraries/LibM/CMakeLists.txt @@ -0,0 +1,10 @@ +set(SOURCES + math.cpp +) + + +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -nostdlib") +serenity_libc(LibM m) +#target_link_libraries(LibM) +#set_target_properties(LibM PROPERTIES OUTPUT_NAME m) +#target_link_directories(LibM PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/Userland/Libraries/LibM/TestMath.cpp b/Userland/Libraries/LibM/TestMath.cpp new file mode 100644 index 0000000000..1a5ce4e87a --- /dev/null +++ b/Userland/Libraries/LibM/TestMath.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <AK/TestSuite.h> + +#include <math.h> + +#define EXPECT_CLOSE(a, b) \ + { \ + EXPECT(fabs(a - b) < 0.000001); \ + } + +TEST_CASE(trig) +{ + EXPECT_CLOSE(sin(1234), 0.653316); + EXPECT_CLOSE(cos(1234), -0.830914); + EXPECT_CLOSE(tan(1234), -0.786262); + EXPECT_CLOSE(sqrt(1234), 35.128336) + EXPECT_CLOSE(sin(-1), -0.867955); + EXPECT_CLOSE(cos(-1), 0.594715); + EXPECT_CLOSE(tan(-1), -1.459446); + EXPECT(isnan(sqrt(-1))); + EXPECT(isnan(asin(1.1))); + EXPECT(isnan(asin(-1.1))); + EXPECT_CLOSE(asin(0), 0.0); + EXPECT_CLOSE(asin(0.01), 0.01); + EXPECT_CLOSE(asin(0.1), 0.100167); + EXPECT_CLOSE(asin(0.3), 0.304693); + EXPECT_CLOSE(asin(0.499), 0.522444); + EXPECT_CLOSE(asin(0.5), 0.523599); + EXPECT_CLOSE(asin(0.501), 0.524754); + EXPECT_CLOSE(asin(0.9), 1.119770); + EXPECT_CLOSE(asin(0.99), 1.429246); + EXPECT_CLOSE(asin(1.0), 1.570750); + EXPECT_CLOSE(atan(0), 0.0) + EXPECT_CLOSE(atan(0.5), 0.463648) + EXPECT_CLOSE(atan(-0.5), -0.463648) + EXPECT_CLOSE(atan(5.5), 1.390943) + EXPECT_CLOSE(atan(-5.5), -1.390943) + EXPECT_CLOSE(atan(555.5), 1.568996) +} + +TEST_CASE(other) +{ + EXPECT_EQ(trunc(9999999999999.5), 9999999999999.0); + EXPECT_EQ(trunc(-9999999999999.5), -9999999999999.0); +} + +TEST_CASE(exponents) +{ + struct values { + double x; + double exp; + double sinh; + double cosh; + double tanh; + }; + + values values[8] { + { 1.500000, 4.481626, 2.129246, 2.352379, 0.905148 }, + { 20.990000, 1304956710.432035, 652478355.216017, 652478355.216017, 1.000000 }, + { 20.010000, 490041186.687082, 245020593.343541, 245020593.343541, 1.000000 }, + { 0.000000, 1.000000, 0.000000, 1.000000, 0.000000 }, + { 0.010000, 1.010050, 0.010000, 1.000050, 0.010000 }, + { -0.010000, 0.990050, -0.010000, 1.000050, -0.010000 }, + { -1.000000, 0.367879, -1.175201, 1.543081, -0.761594 }, + { -17.000000, 0.000000, -12077476.376788, 12077476.376788, -1.000000 }, + }; + for (auto& v : values) { + EXPECT_CLOSE(exp(v.x), v.exp); + EXPECT_CLOSE(sinh(v.x), v.sinh); + EXPECT_CLOSE(cosh(v.x), v.cosh); + EXPECT_CLOSE(tanh(v.x), v.tanh); + } + EXPECT_EQ(exp(1000), std::numeric_limits<double>::infinity()); +} + +TEST_CASE(logarithms) +{ + EXPECT(isnan(log(-1))); + EXPECT(log(0) < -1000000); + EXPECT_CLOSE(log(0.5), -0.693233) + EXPECT_CLOSE(log(1.1), 0.095310) + EXPECT_CLOSE(log(5), 1.609480) + EXPECT_CLOSE(log(5.5), 1.704842) + EXPECT_CLOSE(log(500), 6.214104) + EXPECT_CLOSE(log2(5), 2.321989) + EXPECT_CLOSE(log10(5), 0.698988) +} + +TEST_MAIN(Math) diff --git a/Userland/Libraries/LibM/math.cpp b/Userland/Libraries/LibM/math.cpp new file mode 100644 index 0000000000..2c5c86bdcf --- /dev/null +++ b/Userland/Libraries/LibM/math.cpp @@ -0,0 +1,566 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <LibC/assert.h> +#include <math.h> +#include <stdint.h> +#include <stdlib.h> + +template<size_t> +constexpr double e_to_power(); +template<> +constexpr double e_to_power<0>() { return 1; } +template<size_t exponent> +constexpr double e_to_power() { return M_E * e_to_power<exponent - 1>(); } + +template<size_t> +constexpr size_t factorial(); +template<> +constexpr size_t factorial<0>() { return 1; } +template<size_t value> +constexpr size_t factorial() { return value * factorial<value - 1>(); } + +template<size_t> +constexpr size_t product_even(); +template<> +constexpr size_t product_even<2>() { return 2; } +template<size_t value> +constexpr size_t product_even() { return value * product_even<value - 2>(); } + +template<size_t> +constexpr size_t product_odd(); +template<> +constexpr size_t product_odd<1>() { return 1; } +template<size_t value> +constexpr size_t product_odd() { return value * product_odd<value - 2>(); } + +extern "C" { + +double trunc(double x) NOEXCEPT +{ + return (int64_t)x; +} + +double cos(double angle) NOEXCEPT +{ + return sin(angle + M_PI_2); +} + +float cosf(float angle) NOEXCEPT +{ + return sinf(angle + M_PI_2); +} + +// This can also be done with a taylor expansion, but for +// now this works pretty well (and doesn't mess anything up +// in quake in particular, which is very Floating-Point precision +// heavy) +double sin(double angle) NOEXCEPT +{ + double ret = 0.0; + __asm__( + "fsin" + : "=t"(ret) + : "0"(angle)); + + return ret; +} + +float sinf(float angle) NOEXCEPT +{ + float ret = 0.0f; + __asm__( + "fsin" + : "=t"(ret) + : "0"(angle)); + return ret; +} + +double pow(double x, double y) NOEXCEPT +{ + // FIXME: Please fix me. I am naive. + if (isnan(y)) + return y; + if (y == 0) + return 1; + if (x == 0) + return 0; + if (y == 1) + return x; + int y_as_int = (int)y; + if (y == (double)y_as_int) { + double result = x; + for (int i = 0; i < fabs(y) - 1; ++i) + result *= x; + if (y < 0) + result = 1.0 / result; + return result; + } + return exp2(y * log2(x)); +} + +float powf(float x, float y) NOEXCEPT +{ + return (float)pow(x, y); +} + +double ldexp(double x, int exp) NOEXCEPT +{ + return x * exp2(exp); +} + +float ldexpf(float x, int exp) NOEXCEPT +{ + return x * exp2f(exp); +} + +double tanh(double x) NOEXCEPT +{ + if (x > 0) { + double exponentiated = exp(2 * x); + return (exponentiated - 1) / (exponentiated + 1); + } + double plusX = exp(x); + double minusX = 1 / plusX; + return (plusX - minusX) / (plusX + minusX); +} + +static double ampsin(double angle) NOEXCEPT +{ + double looped_angle = fmod(M_PI + angle, M_TAU) - M_PI; + double looped_angle_squared = looped_angle * looped_angle; + + double quadratic_term; + if (looped_angle > 0) { + quadratic_term = -looped_angle_squared; + } else { + quadratic_term = looped_angle_squared; + } + + double linear_term = M_PI * looped_angle; + + return quadratic_term + linear_term; +} + +double tan(double angle) NOEXCEPT +{ + return ampsin(angle) / ampsin(M_PI_2 + angle); +} + +double sqrt(double x) NOEXCEPT +{ + double res; + __asm__("fsqrt" + : "=t"(res) + : "0"(x)); + return res; +} + +float sqrtf(float x) NOEXCEPT +{ + float res; + __asm__("fsqrt" + : "=t"(res) + : "0"(x)); + return res; +} + +double sinh(double x) NOEXCEPT +{ + double exponentiated = exp(x); + if (x > 0) + return (exponentiated * exponentiated - 1) / 2 / exponentiated; + return (exponentiated - 1 / exponentiated) / 2; +} + +double log10(double x) NOEXCEPT +{ + double ret = 0.0; + __asm__( + "fldlg2\n" + "fld %%st(1)\n" + "fyl2x\n" + "fstp %%st(1)" + : "=t"(ret) + : "0"(x)); + return ret; +} + +double log(double x) NOEXCEPT +{ + double ret = 0.0; + __asm__( + "fldln2\n" + "fld %%st(1)\n" + "fyl2x\n" + "fstp %%st(1)" + : "=t"(ret) + : "0"(x)); + return ret; +} + +float logf(float x) NOEXCEPT +{ + return (float)log(x); +} + +double fmod(double index, double period) NOEXCEPT +{ + return index - trunc(index / period) * period; +} + +float fmodf(float index, float period) NOEXCEPT +{ + return index - trunc(index / period) * period; +} + +double exp(double exponent) NOEXCEPT +{ + double res = 0; + __asm__("fldl2e\n" + "fmulp\n" + "fld1\n" + "fld %%st(1)\n" + "fprem\n" + "f2xm1\n" + "faddp\n" + "fscale\n" + "fstp %%st(1)" + : "=t"(res) + : "0"(exponent)); + return res; +} + +float expf(float exponent) NOEXCEPT +{ + return (float)exp(exponent); +} + +double exp2(double exponent) NOEXCEPT +{ + double res = 0; + __asm__("fld1\n" + "fld %%st(1)\n" + "fprem\n" + "f2xm1\n" + "faddp\n" + "fscale\n" + "fstp %%st(1)" + : "=t"(res) + : "0"(exponent)); + return res; +} + +float exp2f(float exponent) NOEXCEPT +{ + return (float)exp2(exponent); +} + +double cosh(double x) NOEXCEPT +{ + double exponentiated = exp(-x); + if (x < 0) + return (1 + exponentiated * exponentiated) / 2 / exponentiated; + return (1 / exponentiated + exponentiated) / 2; +} + +double atan2(double y, double x) NOEXCEPT +{ + if (x > 0) + return atan(y / x); + if (x == 0) { + if (y > 0) + return M_PI_2; + if (y < 0) + return -M_PI_2; + return 0; + } + if (y >= 0) + return atan(y / x) + M_PI; + return atan(y / x) - M_PI; +} + +float atan2f(float y, float x) NOEXCEPT +{ + return (float)atan2(y, x); +} + +double atan(double x) NOEXCEPT +{ + if (x < 0) + return -atan(-x); + if (x > 1) + return M_PI_2 - atan(1 / x); + double squared = x * x; + 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))))))); +} + +double asin(double x) NOEXCEPT +{ + if (x > 1 || x < -1) + return NAN; + if (x > 0.5 || x < -0.5) + return 2 * atan(x / (1 + sqrt(1 - x * x))); + double squared = x * x; + double value = x; + double i = x * squared; + value += i * product_odd<1>() / product_even<2>() / 3; + i *= squared; + value += i * product_odd<3>() / product_even<4>() / 5; + i *= squared; + value += i * product_odd<5>() / product_even<6>() / 7; + i *= squared; + value += i * product_odd<7>() / product_even<8>() / 9; + i *= squared; + value += i * product_odd<9>() / product_even<10>() / 11; + i *= squared; + value += i * product_odd<11>() / product_even<12>() / 13; + return value; +} + +float asinf(float x) NOEXCEPT +{ + return (float)asin(x); +} + +double acos(double x) NOEXCEPT +{ + return M_PI_2 - asin(x); +} + +float acosf(float x) NOEXCEPT +{ + return M_PI_2 - asinf(x); +} + +double fabs(double value) NOEXCEPT +{ + return value < 0 ? -value : value; +} + +double log2(double x) NOEXCEPT +{ + double ret = 0.0; + __asm__( + "fld1\n" + "fld %%st(1)\n" + "fyl2x\n" + "fstp %%st(1)" + : "=t"(ret) + : "0"(x)); + return ret; +} + +float log2f(float x) NOEXCEPT +{ + return log2(x); +} + +long double log2l(long double x) NOEXCEPT +{ + return log2(x); +} + +double frexp(double, int*) NOEXCEPT +{ + ASSERT_NOT_REACHED(); + return 0; +} + +float frexpf(float, int*) NOEXCEPT +{ + ASSERT_NOT_REACHED(); + return 0; +} + +long double frexpl(long double, int*) NOEXCEPT +{ + ASSERT_NOT_REACHED(); + return 0; +} + +double round(double value) NOEXCEPT +{ + // FIXME: Please fix me. I am naive. + if (value >= 0.0) + return (double)(int)(value + 0.5); + return (double)(int)(value - 0.5); +} + +float roundf(float value) NOEXCEPT +{ + // FIXME: Please fix me. I am naive. + if (value >= 0.0f) + return (float)(int)(value + 0.5f); + return (float)(int)(value - 0.5f); +} + +float floorf(float value) NOEXCEPT +{ + if (value >= 0) + return (int)value; + int intvalue = (int)value; + return ((float)intvalue == value) ? intvalue : intvalue - 1; +} + +double floor(double value) NOEXCEPT +{ + if (value >= 0) + return (int)value; + int intvalue = (int)value; + return ((double)intvalue == value) ? intvalue : intvalue - 1; +} + +double rint(double value) NOEXCEPT +{ + return (int)roundf(value); +} + +float ceilf(float value) NOEXCEPT +{ + // FIXME: Please fix me. I am naive. + int as_int = (int)value; + if (value == (float)as_int) + return as_int; + if (value < 0) { + if (as_int == 0) + return -0; + return as_int; + } + return as_int + 1; +} + +double ceil(double value) NOEXCEPT +{ + // FIXME: Please fix me. I am naive. + int as_int = (int)value; + if (value == (double)as_int) + return as_int; + if (value < 0) { + if (as_int == 0) + return -0; + return as_int; + } + return as_int + 1; +} + +double modf(double x, double* intpart) NOEXCEPT +{ + *intpart = (double)((int)(x)); + return x - (int)x; +} + +double gamma(double x) NOEXCEPT +{ + // Stirling approximation + return sqrt(2.0 * M_PI / x) * pow(x / M_E, x); +} + +double expm1(double x) NOEXCEPT +{ + return exp(x) - 1; +} + +double cbrt(double x) NOEXCEPT +{ + if (isinf(x) || x == 0) + return x; + if (x < 0) + return -cbrt(-x); + + double r = x; + double ex = 0; + + while (r < 0.125) { + r *= 8; + ex--; + } + while (r > 1.0) { + r *= 0.125; + ex++; + } + + r = (-0.46946116 * r + 1.072302) * r + 0.3812513; + + while (ex < 0) { + r *= 0.5; + ex++; + } + while (ex > 0) { + r *= 2; + ex--; + } + + r = (2.0 / 3.0) * r + (1.0 / 3.0) * x / (r * r); + r = (2.0 / 3.0) * r + (1.0 / 3.0) * x / (r * r); + r = (2.0 / 3.0) * r + (1.0 / 3.0) * x / (r * r); + r = (2.0 / 3.0) * r + (1.0 / 3.0) * x / (r * r); + + return r; +} + +double log1p(double x) NOEXCEPT +{ + return log(1 + x); +} + +double acosh(double x) NOEXCEPT +{ + return log(x + sqrt(x * x - 1)); +} + +double asinh(double x) NOEXCEPT +{ + return log(x + sqrt(x * x + 1)); +} + +double atanh(double x) NOEXCEPT +{ + return log((1 + x) / (1 - x)) / 2.0; +} + +double hypot(double x, double y) NOEXCEPT +{ + return sqrt(x * x + y * y); +} + +double erf(double x) NOEXCEPT +{ + // algorithm taken from Abramowitz and Stegun (no. 26.2.17) + double t = 1 / (1 + 0.47047 * fabs(x)); + double poly = t * (0.3480242 + t * (-0.958798 + t * 0.7478556)); + double answer = 1 - poly * exp(-x * x); + if (x < 0) + return -answer; + + return answer; +} + +double erfc(double x) NOEXCEPT +{ + return 1 - erf(x); +} +} diff --git a/Userland/Libraries/LibM/math.h b/Userland/Libraries/LibM/math.h new file mode 100644 index 0000000000..8d9b727ddc --- /dev/null +++ b/Userland/Libraries/LibM/math.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include <sys/cdefs.h> + +#if __cplusplus >= 201103L +# define NOEXCEPT noexcept +#else +# define NOEXCEPT +#endif + +__BEGIN_DECLS + +#define HUGE_VAL 1e10000 +#define INFINITY __builtin_huge_val() +#define NAN __builtin_nan("") +#define M_E 2.718281828459045 +#define M_PI 3.141592653589793 +#define M_PI_2 1.570796326794896 +#define M_TAU 6.283185307179586 +#define M_DEG2RAD 0.017453292519943 +#define M_RAD2DEG 57.29577951308232 +#define M_LN2 0.69314718055995 +#define M_LN10 2.30258509299405 +#define M_SQRT2 1.4142135623730951 +#define M_SQRT1_2 0.7071067811865475 + +#define FP_NAN 0 +#define FP_INFINITE 1 +#define FP_ZERO 2 +#define FP_SUBNORMAL 3 +#define FP_NORMAL 4 +#define fpclassify(x) __builtin_fpclassify(FP_NAN, FP_INFINITE, FP_ZERO, FP_SUBNORMAL, FP_ZERO, x) + +#define signbit(x) __builtin_signbit(x) +#define isnan(x) __builtin_isnan(x) +#define isinf(x) __builtin_isinf_sign(x) +#define isfinite(x) __builtin_isfinite(x) +#define isnormal(x) __builtin_isnormal(x) + +#define DOUBLE_MAX ((double)0b0111111111101111111111111111111111111111111111111111111111111111) +#define DOUBLE_MIN ((double)0b0000000000010000000000000000000000000000000000000000000000000000) + +double acos(double) NOEXCEPT; +float acosf(float) NOEXCEPT; +double asin(double) NOEXCEPT; +float asinf(float) NOEXCEPT; +double atan(double) NOEXCEPT; +float atanf(float) NOEXCEPT; +double atan2(double, double) NOEXCEPT; +float atan2f(float, float) NOEXCEPT; +double cos(double) NOEXCEPT; +float cosf(float) NOEXCEPT; +double cosh(double) NOEXCEPT; +float coshf(float) NOEXCEPT; +double sin(double) NOEXCEPT; +float sinf(float) NOEXCEPT; +double sinh(double) NOEXCEPT; +float sinhf(float) NOEXCEPT; +double tan(double) NOEXCEPT; +float tanf(float) NOEXCEPT; +double tanh(double) NOEXCEPT; +float tanhf(float) NOEXCEPT; +double ceil(double) NOEXCEPT; +float ceilf(float) NOEXCEPT; +double floor(double) NOEXCEPT; +float floorf(float) NOEXCEPT; +double round(double) NOEXCEPT; +float roundf(float) NOEXCEPT; +double fabs(double) NOEXCEPT; +float fabsf(float) NOEXCEPT; +double fmod(double, double) NOEXCEPT; +float fmodf(float, float) NOEXCEPT; +double exp(double) NOEXCEPT; +float expf(float) NOEXCEPT; +double exp2(double) NOEXCEPT; +float exp2f(float) NOEXCEPT; +double frexp(double, int* exp) NOEXCEPT; +float frexpf(float, int* exp) NOEXCEPT; +double log(double) NOEXCEPT; +float logf(float) NOEXCEPT; +double log10(double) NOEXCEPT; +float log10f(float) NOEXCEPT; +double sqrt(double) NOEXCEPT; +float sqrtf(float) NOEXCEPT; +double modf(double, double*) NOEXCEPT; +float modff(float, float*) NOEXCEPT; +double ldexp(double, int exp) NOEXCEPT; +float ldexpf(float, int exp) NOEXCEPT; + +double pow(double x, double y) NOEXCEPT; +float powf(float x, float y) NOEXCEPT; + +double log2(double) NOEXCEPT; +float log2f(float) NOEXCEPT; +long double log2l(long double) NOEXCEPT; +double frexp(double, int*) NOEXCEPT; +float frexpf(float, int*) NOEXCEPT; +long double frexpl(long double, int*) NOEXCEPT; + +double gamma(double) NOEXCEPT; +double expm1(double) NOEXCEPT; +double cbrt(double) NOEXCEPT; +double log1p(double) NOEXCEPT; +double acosh(double) NOEXCEPT; +double asinh(double) NOEXCEPT; +double atanh(double) NOEXCEPT; +double hypot(double, double) NOEXCEPT; +double erf(double) NOEXCEPT; +double erfc(double) NOEXCEPT; + +__END_DECLS |