diff --git a/SHARED-FILES b/SHARED-FILES index 8ea383b370..0c85e2e1b5 100644 --- a/SHARED-FILES +++ b/SHARED-FILES @@ -244,3 +244,7 @@ sysdeps/ieee754/flt-32/s_exp10m1f.c (file src/binary32/exp10m1/exp10m1f.c in CORE-MATH) - The code was adapted to use glibc code style and internal functions to handle errno, overflow, and underflow. +sysdeps/ieee754/flt-32/s_exp2m1f.c + (file src/binary32/exp2m1/exp2m1f.c in CORE-MATH) + - The code was adapted to use glibc code style and internal + functions to handle errno, overflow, and underflow. diff --git a/sysdeps/aarch64/libm-test-ulps b/sysdeps/aarch64/libm-test-ulps index 00832393f6..29ccd1dfe9 100644 --- a/sysdeps/aarch64/libm-test-ulps +++ b/sysdeps/aarch64/libm-test-ulps @@ -1127,22 +1127,18 @@ ldouble: 2 Function: "exp2m1": double: 2 -float: 2 ldouble: 2 Function: "exp2m1_downward": double: 3 -float: 3 ldouble: 3 Function: "exp2m1_towardzero": double: 3 -float: 2 ldouble: 4 Function: "exp2m1_upward": double: 3 -float: 3 ldouble: 5 Function: "exp_advsimd": diff --git a/sysdeps/arc/fpu/libm-test-ulps b/sysdeps/arc/fpu/libm-test-ulps index 4a8ad5142c..a5f9d50c39 100644 --- a/sysdeps/arc/fpu/libm-test-ulps +++ b/sysdeps/arc/fpu/libm-test-ulps @@ -815,19 +815,15 @@ float: 1 Function: "exp2m1": double: 2 -float: 2 Function: "exp2m1_downward": double: 3 -float: 3 Function: "exp2m1_towardzero": double: 3 -float: 2 Function: "exp2m1_upward": double: 3 -float: 3 Function: "exp_downward": double: 1 diff --git a/sysdeps/arc/nofpu/libm-test-ulps b/sysdeps/arc/nofpu/libm-test-ulps index 4cecea6919..574ae8b8be 100644 --- a/sysdeps/arc/nofpu/libm-test-ulps +++ b/sysdeps/arc/nofpu/libm-test-ulps @@ -200,7 +200,6 @@ double: 1 Function: "exp2m1": double: 2 -float: 2 Function: "expm1": double: 1 diff --git a/sysdeps/arm/libm-test-ulps b/sysdeps/arm/libm-test-ulps index bcbe82ca34..28718c7d2c 100644 --- a/sysdeps/arm/libm-test-ulps +++ b/sysdeps/arm/libm-test-ulps @@ -807,19 +807,15 @@ float: 1 Function: "exp2m1": double: 2 -float: 2 Function: "exp2m1_downward": double: 3 -float: 3 Function: "exp2m1_towardzero": double: 3 -float: 2 Function: "exp2m1_upward": double: 3 -float: 3 Function: "exp_downward": double: 1 diff --git a/sysdeps/hppa/fpu/libm-test-ulps b/sysdeps/hppa/fpu/libm-test-ulps index 3dc1f2f8c3..338ca77ade 100644 --- a/sysdeps/hppa/fpu/libm-test-ulps +++ b/sysdeps/hppa/fpu/libm-test-ulps @@ -826,19 +826,15 @@ float: 1 Function: "exp2m1": double: 2 -float: 2 Function: "exp2m1_downward": double: 3 -float: 3 Function: "exp2m1_towardzero": double: 3 -float: 2 Function: "exp2m1_upward": double: 3 -float: 3 Function: "exp_downward": double: 1 diff --git a/sysdeps/i386/fpu/libm-test-ulps b/sysdeps/i386/fpu/libm-test-ulps index 96d02334e4..98a5a538ff 100644 --- a/sysdeps/i386/fpu/libm-test-ulps +++ b/sysdeps/i386/fpu/libm-test-ulps @@ -1194,25 +1194,21 @@ ldouble: 1 Function: "exp2m1": double: 2 -float: 1 float128: 2 ldouble: 3 Function: "exp2m1_downward": double: 3 -float: 3 float128: 3 ldouble: 6 Function: "exp2m1_towardzero": double: 3 -float: 2 float128: 4 ldouble: 5 Function: "exp2m1_upward": double: 3 -float: 3 float128: 5 ldouble: 6 diff --git a/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps b/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps index c18e2bc8de..9afb63bc0f 100644 --- a/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps +++ b/sysdeps/i386/i686/fpu/multiarch/libm-test-ulps @@ -1197,25 +1197,21 @@ ldouble: 1 Function: "exp2m1": double: 2 -float: 1 float128: 2 ldouble: 3 Function: "exp2m1_downward": double: 3 -float: 3 float128: 3 ldouble: 6 Function: "exp2m1_towardzero": double: 3 -float: 2 float128: 4 ldouble: 6 Function: "exp2m1_upward": double: 3 -float: 3 float128: 5 ldouble: 6 diff --git a/sysdeps/ieee754/flt-32/s_exp2m1f.c b/sysdeps/ieee754/flt-32/s_exp2m1f.c new file mode 100644 index 0000000000..f899152d2a --- /dev/null +++ b/sysdeps/ieee754/flt-32/s_exp2m1f.c @@ -0,0 +1,192 @@ +/* Correctly-rounded base-2 exponent function biased by 1 for binary32 value. + +Copyright (c) 2022-2024 Alexei Sibidanov. + +The original version of this file was copied from the CORE-MATH +project (file src/binary32/exp2m1/exp2m1f.c, revision bc385c2). + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ + +#include +#include +#include "math_config.h" +#include +#include +#include + +float +__exp2m1f (float x) +{ + double z = x; + uint32_t ux = asuint (x); + uint32_t ax = ux & (~0u >> 1); + if (__glibc_unlikely (ux >= 0xc1c80000u)) + { /* x <= -25 */ + if (ax > (0xffu << 23)) + return x + x; /* nan */ + return (ux == 0xff800000) ? -0x1p+0 : -0x1p+0 + 0x1p-26f; + } + else if (__glibc_unlikely (ax >= 0x43000000u)) + { /* x >= 128 */ + if (ax >= asuint (INFINITY)) + return x + x; /* +Inf or NaN */ + /* exp2m1 (MAX_EXP) should not overflow when rounding towards zero + or towards -Inf. We round FLT_MAX + 2^103 which is in the middle + between FLT_MAX and 2^128 (the next number with unbounded range). */ + float ret = math_narrow_eval (FLT_MAX + 0x1p103f); + if (x == FLT_MAX_EXP && ret == FLT_MAX) + return ret; + return __math_oflowf (0); + } + else if (__glibc_unlikely (ax < 0x3df95f1fu)) + { /* |x| < 8.44e-2/log(2) */ + double z2 = z * z, r; + if (__glibc_unlikely (ax < 0x3d67a4ccu)) + { /* |x| < 3.92e-2/log(2) */ + if (__glibc_unlikely (ax < 0x3caa2feeu)) + { /* |x| < 1.44e-2/log(2) */ + if (__glibc_unlikely (ax < 0x3bac1405u)) + { /* |x| < 3.64e-3/log(2) */ + if (__glibc_unlikely (ax < 0x3a358876u)) + { /* |x| < 4.8e-4/log(2) */ + if (__glibc_unlikely (ax < 0x37d32ef6u)) + { /* |x| < 1.745e-5/log(2) */ + if (__glibc_unlikely (ax < 0x331fdd82u)) + { /* |x| < 2.58e-8/log(2) */ + if (__glibc_unlikely (ax < 0x2538aa3bu)) + /* |x| < 1.60171e-16 */ + r = 0x1.62e42fefa39efp-1; + else + r = 0x1.62e42fefa39fp-1 + + z * 0x1.ebfbdff82c58fp-3; + } + else + { + if (__glibc_unlikely (ux == 0xb3d85005u)) + return -0x1.2bdf76p-24 - 0x1.8p-77; + if (__glibc_unlikely (ux == 0x3338428du)) + return 0x1.fee08ap-26 + 0x1p-80; + static const double c[] = + { + 0x1.62e42fefa39efp-1, 0x1.ebfbdff8548fdp-3, + 0x1.c6b08d704a06dp-5 + }; + r = c[0] + z * (c[1] + z * c[2]); + } + } + else + { + if (__glibc_unlikely (ux == 0x388bca4fu)) + return 0x1.839702p-15 - 0x1.8p-68; + static const double c[] = + { + 0x1.62e42fefa39efp-1, 0x1.ebfbdff82c58fp-3, + 0x1.c6b08dc82b347p-5, 0x1.3b2ab6fbad172p-7 + }; + r = (c[0] + z * c[1]) + z2 * (c[2] + z * c[3]); + } + } + else + { + static const double c[] = + { + 0x1.62e42fefa39efp-1, 0x1.ebfbdff82c068p-3, + 0x1.c6b08d704a6dcp-5, 0x1.3b2ac262c3eedp-7, + 0x1.5d87fe7af779ap-10 + }; + r = (c[0] + z * c[1]) + + z2 * (c[2] + z * (c[3] + z * c[4])); + } + } + else + { + static const double c[] = + { + 0x1.62e42fefa39fp-1, 0x1.ebfbdff82c58dp-3, + 0x1.c6b08d7011d13p-5, 0x1.3b2ab6fbd267dp-7, + 0x1.5d88a81cea49ep-10, 0x1.430912ea9b963p-13 + }; + r = (c[0] + z * c[1]) + + z2 * ((c[2] + z * c[3]) + z2 * (c[4] + z * c[5])); + } + } + else + { + static const double c[] = + { + 0x1.62e42fefa39efp-1, 0x1.ebfbdff82c639p-3, + 0x1.c6b08d7049f1cp-5, 0x1.3b2ab6f5243bdp-7, + 0x1.5d87fe80a9e6cp-10, 0x1.430d0b9257fa8p-13, + 0x1.ffcbfc4cf0952p-17 + }; + r = (c[0] + z * c[1]) + + z2 * ((c[2] + z * c[3]) + + z2 * (c[4] + z * (c[5] + z * c[6]))); + } + } + else + { + static const double c[] = + { + 0x1.62e42fefa39efp-1, 0x1.ebfbdff82c591p-3, + 0x1.c6b08d704cf6bp-5, 0x1.3b2ab6fba00cep-7, + 0x1.5d87fdfdaadb4p-10, 0x1.4309137333066p-13, + 0x1.ffe5e90daf7ddp-17, 0x1.62c0220eed731p-20 + }; + r = ((c[0] + z * c[1]) + z2 * (c[2] + z * c[3])) + + (z2 * z2) * ((c[4] + z * c[5]) + z2 * (c[6] + z * c[7])); + } + r *= z; + return r; + } + else + { + static const double c[] = + { + 0x1.62e42fefa398bp-5, 0x1.ebfbdff84555ap-11, + 0x1.c6b08d4ad86d3p-17, 0x1.3b2ad1b1716a2p-23, + 0x1.5d7472718ce9dp-30, 0x1.4a1d7f457ac56p-37 + }; + static const double tb[] = + { + 0x1p+0, 0x1.0b5586cf9890fp+0, 0x1.172b83c7d517bp+0, + 0x1.2387a6e756238p+0, 0x1.306fe0a31b715p+0, 0x1.3dea64c123422p+0, + 0x1.4bfdad5362a27p+0, 0x1.5ab07dd485429p+0, 0x1.6a09e667f3bcdp+0, + 0x1.7a11473eb0187p+0, 0x1.8ace5422aa0dap+0, 0x1.9c49182a3f09p+0, + 0x1.ae89f995ad3adp+0, 0x1.c199bdd85529cp+0, 0x1.d5818dcfba487p+0, + 0x1.ea4afa2a490dap+0 + }; + double a = 16.0 * z; + double ia = floor (a); + double h = a - ia; + double h2 = h * h; + int64_t i = ia, j = i & 0xf, e = i - j; + e >>= 4; + double s = tb[j]; + s *= asdouble ((e + 0x3ffull) << 52); + double c0 = c[0] + h * c[1]; + double c2 = c[2] + h * c[3]; + double c4 = c[4] + h * c[5]; + c0 += h2 * (c2 + h2 * c4); + double w = s * h; + return (s - 1.0) + w * c0; + } +} +libm_alias_float (__exp2m1, exp2m1) diff --git a/sysdeps/loongarch/lp64/libm-test-ulps b/sysdeps/loongarch/lp64/libm-test-ulps index de7e526008..c6fc9fd4ed 100644 --- a/sysdeps/loongarch/lp64/libm-test-ulps +++ b/sysdeps/loongarch/lp64/libm-test-ulps @@ -1010,22 +1010,18 @@ ldouble: 2 Function: "exp2m1": double: 2 -float: 2 ldouble: 2 Function: "exp2m1_downward": double: 3 -float: 3 ldouble: 3 Function: "exp2m1_towardzero": double: 3 -float: 2 ldouble: 4 Function: "exp2m1_upward": double: 3 -float: 3 ldouble: 5 Function: "exp_downward": diff --git a/sysdeps/m68k/m680x0/fpu/libm-test-ulps b/sysdeps/m68k/m680x0/fpu/libm-test-ulps index 96cd7b3fd5..7fef8942ae 100644 --- a/sysdeps/m68k/m680x0/fpu/libm-test-ulps +++ b/sysdeps/m68k/m680x0/fpu/libm-test-ulps @@ -903,19 +903,15 @@ double: 1 Function: "exp2m1": double: 1 -float: 1 Function: "exp2m1_downward": double: 2 -float: 1 Function: "exp2m1_towardzero": double: 2 -float: 1 Function: "exp2m1_upward": double: 1 -float: 1 Function: "exp_upward": double: 1 diff --git a/sysdeps/mips/mips32/libm-test-ulps b/sysdeps/mips/mips32/libm-test-ulps index 829da3ebf1..d8daca6326 100644 --- a/sysdeps/mips/mips32/libm-test-ulps +++ b/sysdeps/mips/mips32/libm-test-ulps @@ -807,19 +807,15 @@ float: 1 Function: "exp2m1": double: 2 -float: 2 Function: "exp2m1_downward": double: 3 -float: 3 Function: "exp2m1_towardzero": double: 3 -float: 2 Function: "exp2m1_upward": double: 3 -float: 3 Function: "exp_downward": double: 1 diff --git a/sysdeps/mips/mips64/libm-test-ulps b/sysdeps/mips/mips64/libm-test-ulps index 5c7b050b11..39e94d5480 100644 --- a/sysdeps/mips/mips64/libm-test-ulps +++ b/sysdeps/mips/mips64/libm-test-ulps @@ -1014,22 +1014,18 @@ ldouble: 2 Function: "exp2m1": double: 2 -float: 2 ldouble: 2 Function: "exp2m1_downward": double: 3 -float: 3 ldouble: 3 Function: "exp2m1_towardzero": double: 3 -float: 2 ldouble: 4 Function: "exp2m1_upward": double: 3 -float: 3 ldouble: 5 Function: "exp_downward": diff --git a/sysdeps/powerpc/fpu/libm-test-ulps b/sysdeps/powerpc/fpu/libm-test-ulps index 30ddbaf05f..dd25aaf94a 100644 --- a/sysdeps/powerpc/fpu/libm-test-ulps +++ b/sysdeps/powerpc/fpu/libm-test-ulps @@ -1227,25 +1227,21 @@ ldouble: 2 Function: "exp2m1": double: 2 -float: 2 float128: 2 ldouble: 3 Function: "exp2m1_downward": double: 3 -float: 3 float128: 3 ldouble: 7 Function: "exp2m1_towardzero": double: 3 -float: 2 float128: 4 ldouble: 8 Function: "exp2m1_upward": double: 3 -float: 3 float128: 5 ldouble: 9 diff --git a/sysdeps/powerpc/nofpu/libm-test-ulps b/sysdeps/powerpc/nofpu/libm-test-ulps index e15e1f8fc0..1e5bae039b 100644 --- a/sysdeps/powerpc/nofpu/libm-test-ulps +++ b/sysdeps/powerpc/nofpu/libm-test-ulps @@ -1023,22 +1023,18 @@ ldouble: 2 Function: "exp2m1": double: 2 -float: 2 ldouble: 2 Function: "exp2m1_downward": double: 3 -float: 3 ldouble: 7 Function: "exp2m1_towardzero": double: 3 -float: 2 ldouble: 8 Function: "exp2m1_upward": double: 3 -float: 3 ldouble: 9 Function: "exp_downward": diff --git a/sysdeps/riscv/nofpu/libm-test-ulps b/sysdeps/riscv/nofpu/libm-test-ulps index 2271e1ee6c..11f891988e 100644 --- a/sysdeps/riscv/nofpu/libm-test-ulps +++ b/sysdeps/riscv/nofpu/libm-test-ulps @@ -995,7 +995,6 @@ ldouble: 2 Function: "exp2m1": double: 1 -float: 1 ldouble: 1 Function: "exp_downward": diff --git a/sysdeps/riscv/rvd/libm-test-ulps b/sysdeps/riscv/rvd/libm-test-ulps index 0bc61bf3c8..7d303fcb6b 100644 --- a/sysdeps/riscv/rvd/libm-test-ulps +++ b/sysdeps/riscv/rvd/libm-test-ulps @@ -1010,22 +1010,18 @@ ldouble: 2 Function: "exp2m1": double: 2 -float: 2 ldouble: 2 Function: "exp2m1_downward": double: 3 -float: 3 ldouble: 3 Function: "exp2m1_towardzero": double: 3 -float: 2 ldouble: 4 Function: "exp2m1_upward": double: 3 -float: 3 ldouble: 5 Function: "exp_downward": diff --git a/sysdeps/s390/fpu/libm-test-ulps b/sysdeps/s390/fpu/libm-test-ulps index 860479f3ff..aa7a94a2be 100644 --- a/sysdeps/s390/fpu/libm-test-ulps +++ b/sysdeps/s390/fpu/libm-test-ulps @@ -1011,22 +1011,18 @@ ldouble: 2 Function: "exp2m1": double: 2 -float: 2 ldouble: 2 Function: "exp2m1_downward": double: 3 -float: 3 ldouble: 3 Function: "exp2m1_towardzero": double: 3 -float: 2 ldouble: 4 Function: "exp2m1_upward": double: 3 -float: 3 ldouble: 5 Function: "exp_downward": diff --git a/sysdeps/sparc/fpu/libm-test-ulps b/sysdeps/sparc/fpu/libm-test-ulps index 4d8064b543..e7b3da6f1c 100644 --- a/sysdeps/sparc/fpu/libm-test-ulps +++ b/sysdeps/sparc/fpu/libm-test-ulps @@ -1014,22 +1014,18 @@ ldouble: 2 Function: "exp2m1": double: 2 -float: 2 ldouble: 2 Function: "exp2m1_downward": double: 3 -float: 3 ldouble: 3 Function: "exp2m1_towardzero": double: 3 -float: 2 ldouble: 4 Function: "exp2m1_upward": double: 3 -float: 3 ldouble: 5 Function: "exp_downward": diff --git a/sysdeps/x86_64/fpu/libm-test-ulps b/sysdeps/x86_64/fpu/libm-test-ulps index 3f438c2090..71697e99e0 100644 --- a/sysdeps/x86_64/fpu/libm-test-ulps +++ b/sysdeps/x86_64/fpu/libm-test-ulps @@ -1495,25 +1495,21 @@ float: 1 Function: "exp2m1": double: 2 -float: 2 float128: 2 ldouble: 3 Function: "exp2m1_downward": double: 3 -float: 3 float128: 3 ldouble: 6 Function: "exp2m1_towardzero": double: 3 -float: 2 float128: 4 ldouble: 5 Function: "exp2m1_upward": double: 3 -float: 3 float128: 5 ldouble: 6