[PATCH v2 08/13] math: Order signed zeros in f{max,min}mag{f,l,f128}
Adhemerval Zanella
adhemerval.zanella@linaro.org
Fri Jan 23 13:02:21 GMT 2026
The functions are documented to behave like fmax/fmin when the
arguments have the same absolute value.
Checked on x86_64-linux-gnu, aarch64-linux-gnu, i686-linux-gnu,
arm-linux-gnueabihf, powerpc64le-linux-gnu,
riscv64-linux-gnu-rv64imafdc-lp64d, and loongarch64-linux-gnuf64.
---
manual/arith.texi | 3 ++-
math/libm-test-fmaxmag.inc | 5 +++--
math/libm-test-fminmag.inc | 5 +++--
math/s_fmaxmag_template.c | 2 +-
math/s_fminmag_template.c | 2 +-
5 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/manual/arith.texi b/manual/arith.texi
index 7846b6903e..df6d25e0ba 100644
--- a/manual/arith.texi
+++ b/manual/arith.texi
@@ -2201,7 +2201,8 @@ treated as greater than negative zero.
These functions, from TS 18661-1:2014 and TS 18661-3:2015, return
whichever of the two values @var{x} and @var{y} has the smaller absolute
value. If both have the same absolute value, or either is NaN, they
-behave the same as the @code{fmin} functions.
+behave the same as the @code{fmin} functions (including the order of
+signed zeros).
@end deftypefun
@deftypefun double fmaxmag (double @var{x}, double @var{y})
diff --git a/math/libm-test-fmaxmag.inc b/math/libm-test-fmaxmag.inc
index 3940a45536..45f3873225 100644
--- a/math/libm-test-fmaxmag.inc
+++ b/math/libm-test-fmaxmag.inc
@@ -22,8 +22,9 @@ static const struct test_ff_f_data fmaxmag_test_data[] =
{
TEST_ff_f (fmaxmag, 0, 0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fmaxmag, minus_zero, minus_zero, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
- TEST_ff_f (fmaxmag, 0, minus_zero, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|IGNORE_ZERO_INF_SIGN),
- TEST_ff_f (fmaxmag, minus_zero, 0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|IGNORE_ZERO_INF_SIGN),
+ /* The order signed zeros are implemented as a QoI in the generic implementation. */
+ TEST_ff_f (fmaxmag, 0, minus_zero, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fmaxmag, minus_zero, 0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fmaxmag, min_subnorm_value, min_subnorm_value, min_subnorm_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fmaxmag, min_subnorm_value, -min_subnorm_value, min_subnorm_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fmaxmag, -min_subnorm_value, min_subnorm_value, min_subnorm_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
diff --git a/math/libm-test-fminmag.inc b/math/libm-test-fminmag.inc
index 5c80e84de3..979b10eb97 100644
--- a/math/libm-test-fminmag.inc
+++ b/math/libm-test-fminmag.inc
@@ -22,8 +22,9 @@ static const struct test_ff_f_data fminmag_test_data[] =
{
TEST_ff_f (fminmag, 0, 0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fminmag, minus_zero, minus_zero, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
- TEST_ff_f (fminmag, 0, minus_zero, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|IGNORE_ZERO_INF_SIGN),
- TEST_ff_f (fminmag, minus_zero, 0, 0, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED|IGNORE_ZERO_INF_SIGN),
+ /* The order signed zeros are implemented as a QoI in the generic implementation. */
+ TEST_ff_f (fminmag, 0, minus_zero, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
+ TEST_ff_f (fminmag, minus_zero, 0, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fminmag, min_subnorm_value, min_subnorm_value, min_subnorm_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fminmag, min_subnorm_value, -min_subnorm_value, -min_subnorm_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
TEST_ff_f (fminmag, -min_subnorm_value, min_subnorm_value, -min_subnorm_value, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
diff --git a/math/s_fmaxmag_template.c b/math/s_fmaxmag_template.c
index 915f199283..11df91d092 100644
--- a/math/s_fmaxmag_template.c
+++ b/math/s_fmaxmag_template.c
@@ -26,7 +26,7 @@ M_DECL_FUNC (__fmaxmag) (FLOAT x, FLOAT y)
FLOAT ax = M_FABS (x);
FLOAT ay = M_FABS (y);
if (__glibc_unlikely (ax == ay))
- return x > y ? x : y;
+ return signbit (x) ? y : x;
return isgreater (ax, ay) ? x : y;
}
else if (issignaling (x) || issignaling (y))
diff --git a/math/s_fminmag_template.c b/math/s_fminmag_template.c
index d4960baefa..88fbac61e5 100644
--- a/math/s_fminmag_template.c
+++ b/math/s_fminmag_template.c
@@ -26,7 +26,7 @@ M_DECL_FUNC (__fminmag) (FLOAT x, FLOAT y)
FLOAT ax = M_FABS (x);
FLOAT ay = M_FABS (y);
if (__glibc_unlikely (ax == ay))
- return x < y ? x : y;
+ return signbit (x) ? x : y;
return isless (ax, ay) ? x : y;
}
else if (issignaling (x) || issignaling (y))
--
2.43.0
More information about the Libc-alpha
mailing list