diff options
| author | Joseph Myers <josmyers@redhat.com> | 2025-03-14 15:58:11 +0000 |
|---|---|---|
| committer | Joseph Myers <josmyers@redhat.com> | 2025-03-14 15:58:11 +0000 |
| commit | 409668f6e88b63607e2cea29b3ce2a1c25f04bf1 (patch) | |
| tree | 0711db25c83b4f0bb67fd02ceddd707d561f5e33 | |
| parent | c7c4a5906f326f1290b1c2413a83c530564ec4b8 (diff) | |
| download | glibc-409668f6e88b63607e2cea29b3ce2a1c25f04bf1.tar.xz glibc-409668f6e88b63607e2cea29b3ce2a1c25f04bf1.zip | |
Implement C23 powr
C23 adds various <math.h> function families originally defined in TS
18661-4. Add the powr functions, which are like pow, but with simpler
handling of special cases (based on exp(y*log(x)), so negative x and
0^0 are domain errors, powers of -0 are always +0 or +Inf never -0 or
-Inf, and 1^+-Inf and Inf^0 are also domain errors, while NaN^0 and
1^NaN are NaN). The test inputs are taken from those for pow, with
appropriate adjustments (including removing all tests that would be
domain errors from those in auto-libm-test-in and adding some more
such tests in libm-test-powr.inc).
The underlying implementation uses __ieee754_pow functions after
dealing with all special cases that need to be handled differently.
It might be a little faster (avoiding a wrapper and redundant checks
for special cases) to have an underlying implementation built
separately for both pow and powr with compile-time conditionals for
special-case handling, but I expect the benefit of that would be
limited given that both functions will end up needing to use the same
logic for computing pow outside of special cases.
My understanding is that powr(negative, qNaN) should raise "invalid":
that the rule on "invalid" for an argument outside the domain of the
function takes precedence over a quiet NaN argument producing a quiet
NaN result with no exceptions raised (for rootn it's explicit that the
0th root of qNaN raises "invalid"). I've raised this on the WG14
reflector to confirm the intent.
Tested for x86_64 and x86, and with build-many-glibcs.py.
48 files changed, 18866 insertions, 2 deletions
@@ -14,7 +14,7 @@ Major new features: functions for float, double, long double, _FloatN and _FloatNx, and a type-generic macro in <tgmath.h>. - - Power and absolute-value functions: rsqrt. + - Power and absolute-value functions: powr, rsqrt. * On Linux, the pthread_gettid_np function has been added. diff --git a/manual/math.texi b/manual/math.texi index a947585d70..7490693c0d 100644 --- a/manual/math.texi +++ b/manual/math.texi @@ -774,6 +774,21 @@ do that, so instead it signals a domain error. @code{pow} may also underflow or overflow the destination type. @end deftypefun +@deftypefun double powr (double @var{base}, double @var{power}) +@deftypefunx float powrf (float @var{base}, float @var{power}) +@deftypefunx {long double} powrl (long double @var{base}, long double @var{power}) +@deftypefunx _FloatN powrfN (_Float@var{N} @var{base}, _Float@var{N} @var{power}) +@deftypefunx _FloatNx powrfNx (_Float@var{N}x @var{base}, _Float@var{N}x @var{power}) +@standards{TS 18661-4:2015, math.h} +@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}} +These return @var{base} raised to @var{power}, but with special cases +based on @code{exp (power * log (base))}. For example, if @var{base} +is negative, the @code{powr} functions always signal a domain error, +but this is valid for @code{pow} if @var{power} is an integer. + +The @code{powr} functions are from TS 18661-4:2015. +@end deftypefun + @cindex square root function @deftypefun double sqrt (double @var{x}) @deftypefunx float sqrtf (float @var{x}) diff --git a/math/Makefile b/math/Makefile index b1d7c767f7..64d9d4d1e5 100644 --- a/math/Makefile +++ b/math/Makefile @@ -139,6 +139,7 @@ gen-libm-calls = \ s_log2p1F \ s_nanF \ s_nextdownF \ + s_powrF \ s_rsqrtF \ s_significandF \ s_sinpiF \ @@ -685,6 +686,7 @@ libm-test-funcs-auto = \ log1p \ log2p1 \ pow \ + powr \ rsqrt \ sin \ sincos \ @@ -1016,6 +1018,7 @@ tgmath3-macros = \ nexttoward \ nextup \ pow \ + powr \ remainder \ remquo \ rint \ @@ -1439,6 +1442,7 @@ CFLAGS-s_nexttoward.c += -fno-builtin-nexttoward -fno-builtin-nexttowardl CFLAGS-s_nexttowardf.c += -fno-builtin-nexttowardf CFLAGS-s_nextup.c += -fno-builtin-nextupl CFLAGS-e_pow.c += -fno-builtin-powl +CFLAGS-s_powr.c += -fno-builtin-powrl CFLAGS-w_remainder.c += -fno-builtin-remainderl -fno-builtin-dreml CFLAGS-s_remquo.c += -fno-builtin-remquol CFLAGS-s_rint.c += -fno-builtin-rintl @@ -1574,6 +1578,7 @@ CFLAGS-s_nextafter.c += -fno-builtin-nextafterf32x -fno-builtin-nextafterf64 CFLAGS-s_nextdown.c += -fno-builtin-nextdownf32x -fno-builtin-nextdownf64 CFLAGS-s_nextup.c += -fno-builtin-nextupf32x -fno-builtin-nextupf64 CFLAGS-e_pow.c += -fno-builtin-powf32x -fno-builtin-powf64 +CFLAGS-s_powr.c += -fno-builtin-powrf32x -fno-builtin-powrf64 CFLAGS-w_remainder.c += -fno-builtin-remainderf32x -fno-builtin-remainderf64 CFLAGS-s_remquo.c += -fno-builtin-remquof32x -fno-builtin-remquof64 CFLAGS-s_rint.c += -fno-builtin-rintf32x -fno-builtin-rintf64 @@ -1700,6 +1705,7 @@ CFLAGS-s_nextafterf.c += -fno-builtin-nextafterf32 CFLAGS-s_nextdownf.c += -fno-builtin-nextdownf32 CFLAGS-s_nextupf.c += -fno-builtin-nextupf32 CFLAGS-e_powf.c += -fno-builtin-powf32 +CFLAGS-s_powrf.c += -fno-builtin-powrf32 CFLAGS-w_remainderf.c += -fno-builtin-remainderf32 CFLAGS-s_remquof.c += -fno-builtin-remquof32 CFLAGS-s_rintf.c += -fno-builtin-rintf32 diff --git a/math/Versions b/math/Versions index 34cdf2f8e8..f92707545a 100644 --- a/math/Versions +++ b/math/Versions @@ -673,8 +673,10 @@ libm { } GLIBC_2.42 { # Functions not involving _Float64x or _Float128, for all configurations. + powr; powrf; powrl; powrf32; powrf64; powrf32x; rsqrt; rsqrtf; rsqrtl; rsqrtf32; rsqrtf64; rsqrtf32x; # Functions involving _Float64x or _Float128, for some configurations. + powrf64x; powrf128; rsqrtf64x; rsqrtf128; } } diff --git a/math/auto-libm-test-in b/math/auto-libm-test-in index 989ce5d736..09069e985d 100644 --- a/math/auto-libm-test-in +++ b/math/auto-libm-test-in @@ -8151,6 +8151,313 @@ pow 0x1.059c76p+0 0x1.ff80bep+11 pow 0x1.7ac7cp+5 23 pow -0x1.7ac7cp+5 23 +powr 10 0 +powr 10 -0 + +powr 1 1 +powr 1 -1 +powr 1 1.25 +powr 1 -1.25 +powr 1 0x1p62 +powr 1 0x1p63 +powr 1 0x1p64 +powr 1 0x1p72 +powr 1 min_subnorm +powr 1 -min_subnorm + +# powr (x, +-0) == 1. +powr 32.75 0 +powr 32.75 -0 +powr 0x1p72 0 +powr 0x1p72 -0 +powr 0x1p-72 0 +powr 0x1p-72 -0 + +powr 0x1p72 0x1p72 +powr 10 -0x1p72 +powr max max +powr 10 -max + +powr 0 1 +powr 0 11 + +powr -0 1 +powr -0 11 + +powr 0 2 +powr 0 11.1 + +powr -0 2 +powr -0 11.1 + +# powr (+0, y) == +0 for y an odd integer > 0. +powr 0.0 27 +powr 0.0 0xffffff +powr 0.0 0x1.fffffffffffffp+52 +powr 0.0 0x1.fffffffffffffffep+63 +powr 0.0 0x1.ffffffffffffffffffffffffff8p+105 +powr 0.0 0x1.ffffffffffffffffffffffffffffp+112 + +# powr (-0, y) == +0 (unlike pow) for y an odd integer > 0. +powr -0 27 +powr -0 0xffffff +powr -0 0x1fffffe +powr -0 0x1.fffffffffffffp+52 +powr -0 0x1.fffffffffffffp+53 +powr -0 0x1.fffffffffffffffep+63 +powr -0 0x1.fffffffffffffffep+64 xfail-rounding:ibm128-libgcc +powr -0 0x1.ffffffffffffffffffffffffff8p+105 xfail-rounding:ibm128-libgcc +powr -0 0x1.ffffffffffffffffffffffffff8p+106 xfail-rounding:ibm128-libgcc +powr -0 0x1.ffffffffffffffffffffffffffffp+112 xfail-rounding:ibm128-libgcc +powr -0 0x1.ffffffffffffffffffffffffffffp+113 xfail-rounding:ibm128-libgcc + +# powr (+0, y) == +0 for y > 0 and not an odd integer. +powr 0.0 4 +powr 0.0 0x1p24 +powr 0.0 0x1p127 +powr 0.0 max +powr 0.0 min_subnorm + +# powr (-0, y) == +0 for y > 0 and not an odd integer. +powr -0 0.5 +powr -0 4 +powr -0 0x1p24 +powr -0 0x1p127 +powr -0 max +powr -0 min_subnorm + +powr 16 0.25 +powr 0x1p64 0.125 +powr 2 4 +powr 256 8 + +powr 0.75 1.25 + +powr 0x0.ffffffp0 10 +powr 0x0.ffffffp0 100 +powr 0x0.ffffffp0 1000 +powr 0x0.ffffffp0 0x1p24 +powr 0x0.ffffffp0 0x1p30 +powr 0x0.ffffffp0 0x1.234566p30 +powr 0x0.ffffffp0 -10 +powr 0x0.ffffffp0 -100 +powr 0x0.ffffffp0 -1000 +powr 0x0.ffffffp0 -0x1p24 +powr 0x0.ffffffp0 -0x1p30 +powr 0x0.ffffffp0 -0x1.234566p30 +powr 0x1.000002p0 0x1p24 +powr 0x1.000002p0 0x1.234566p29 +powr 0x1.000002p0 -0x1.234566p29 + +powr 0x0.fffffffffffff8p0 0x1.23456789abcdfp62 +powr 0x0.fffffffffffff8p0 -0x1.23456789abcdfp62 +powr 0x1.0000000000001p0 0x1.23456789abcdfp61 +powr 0x1.0000000000001p0 -0x1.23456789abcdfp61 + +powr 0x0.ffffffffffffffffp0 0x1.23456789abcdef0ep77 +powr 0x0.ffffffffffffffffp0 -0x1.23456789abcdef0ep77 +powr 0x1.0000000000000002p0 0x1.23456789abcdef0ep76 +powr 0x1.0000000000000002p0 -0x1.23456789abcdef0ep76 + +powr 0x0.ffffffffffffffffffffffffffff8p0 0x1.23456789abcdef0123456789abcdp126 +powr 0x0.ffffffffffffffffffffffffffff8p0 -0x1.23456789abcdef0123456789abcdp126 +powr 0x1.0000000000000000000000000001p0 0x1.23456789abcdef0123456789abcdp125 +powr 0x1.0000000000000000000000000001p0 -0x1.23456789abcdef0123456789abcdp125 + +powr 0x1.000002p0 0x1p30 +powr 0x1.000002p0 max +powr 0x1.00000ep0 0x1p30 +powr 0x1.00000ep0 max + +powr 1e4932 0.75 +powr 1e4928 0.75 +powr 1e4924 0.75 +powr 1e4920 0.75 +powr 10.0 4932.0 +powr 10.0 4931.0 +powr 10.0 4930.0 +powr 10.0 4929.0 +powr 10.0 -4931.0 +powr 10.0 -4930.0 +powr 10.0 -4929.0 +powr 1e27 182.0 +powr 1e27 -182.0 + +powr min_subnorm min_subnorm +powr min_subnorm -min_subnorm +powr max min_subnorm +powr max -min_subnorm +powr 0.99 min_subnorm +powr 0.99 -min_subnorm +powr 1.01 min_subnorm +powr 1.01 -min_subnorm + +powr 2.0 -100000.0 + +powr 2 -126.125 +powr 2 -126.25 +powr 2 -126.375 +powr 2 -126.5 +powr 2 -126.625 +powr 2 -126.75 +powr 2 -126.875 +powr 2 -969.125 +powr 2 -969.25 +powr 2 -969.375 +powr 2 -969.5 +powr 2 -969.625 +powr 2 -969.75 +powr 2 -969.875 +powr 2 -1022.125 +powr 2 -1022.25 +powr 2 -1022.375 +powr 2 -1022.5 +powr 2 -1022.625 +powr 2 -1022.75 +powr 2 -1022.875 +powr 2 -16382.125 +powr 2 -16382.25 +powr 2 -16382.375 +powr 2 -16382.5 +powr 2 -16382.625 +powr 2 -16382.75 +powr 2 -16382.875 +powr 2 -16383.125 +powr 2 -16383.25 +powr 2 -16383.375 +powr 2 -16383.5 +powr 2 -16383.625 +powr 2 -16383.75 +powr 2 -16383.875 +powr 0.5 126.125 +powr 0.5 126.25 +powr 0.5 126.375 +powr 0.5 126.5 +powr 0.5 126.625 +powr 0.5 126.75 +powr 0.5 126.875 +powr 0.5 969.125 +powr 0.5 969.25 +powr 0.5 969.375 +powr 0.5 969.5 +powr 0.5 969.625 +powr 0.5 969.75 +powr 0.5 969.875 +powr 0.5 1022.125 +powr 0.5 1022.25 +powr 0.5 1022.375 +powr 0.5 1022.5 +powr 0.5 1022.625 +powr 0.5 1022.75 +powr 0.5 1022.875 +powr 0.5 16382.125 +powr 0.5 16382.25 +powr 0.5 16382.375 +powr 0.5 16382.5 +powr 0.5 16382.625 +powr 0.5 16382.75 +powr 0.5 16382.875 +powr 0.5 16383.125 +powr 0.5 16383.25 +powr 0.5 16383.375 +powr 0.5 16383.5 +powr 0.5 16383.625 +powr 0.5 16383.75 +powr 0.5 16383.875 +powr 0x1.00001p1 -126 +powr 0x1.00003p1 -126 +powr 0x1.00005p1 -126 +powr 0x1.00007p1 -126 +powr 0x1.00001p1 -969 +powr 0x1.00003p1 -969 +powr 0x1.00005p1 -969 +powr 0x1.00007p1 -969 +powr 0x1.00001p1 -1022 +powr 0x1.00003p1 -1022 +powr 0x1.00005p1 -1022 +powr 0x1.00007p1 -1022 +powr 0x1.00001p1 -16382 +powr 0x1.00003p1 -16382 |
