[PATCH] sysdeps/ieee754/flt-32: Fix remainderf() sign of zero for FE_DOWNWARD
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Mon Feb 17 14:58:36 GMT 2025
On 17/02/25 06:40, Sergei Zimmerman wrote:
> Single-precision remainderf() implementation derived from Sun is
> affected by an issue when the result is +-0. IEEE754 requires that
> if remainder(x, y) = 0, its sign shall be that of x regardless of the
> rounding direction.
>
> The implementation seems to have assumed that x - x = +0 in all
> rounding modes, which is not the case. When rounding direction is
> roundTowardNegative the sign of an exact zero sum (or difference) is −0.
>
> Regression tests that triggered this erroneous behavior are added to
> math/libm-test-remainder.inc.
>
> Original fix by: Bruce Evans <bde@FreeBSD.org> in FreeBSD's
> a2ddfa5ea726c56dbf825763ad371c261b89b7c7.
> ---
> math/libm-test-remainder.inc | 4 ++++
> sysdeps/ieee754/flt-32/e_remainderf.c | 3 +++
> 2 files changed, 7 insertions(+)
>
> diff --git a/math/libm-test-remainder.inc b/math/libm-test-remainder.inc
> index 1a1d3e9937..f2b0104087 100644
> --- a/math/libm-test-remainder.inc
> +++ b/math/libm-test-remainder.inc
> @@ -173,6 +173,10 @@ static const struct test_ff_f_data remainder_test_data[] =
> TEST_ff_f (remainder, 2, -1, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
> TEST_ff_f (remainder, -2, 1, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
> TEST_ff_f (remainder, -2, -1, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
> +
> + TEST_ff_f (remainder, 0x1.08001cp-2, 0x1p-24, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
> + TEST_ff_f (remainder, -0x1.003ffep-126, -0x1.8p-148, minus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
> + TEST_ff_f (remainder, 0x1.2c3224p+17, 0x1p-5, plus_zero, NO_INEXACT_EXCEPTION|ERRNO_UNCHANGED),
> };
>
> static void
This new test added a regression for other implementation (dbl-128
and ldbl-128ibm), and I have opened a bug report to track it [1]
I think we will need to either fix on all implementation (which
should be easy), or just enable the tests for float.
[1] https://sourceware.org/bugzilla/show_bug.cgi?id=32711
> diff --git a/sysdeps/ieee754/flt-32/e_remainderf.c b/sysdeps/ieee754/flt-32/e_remainderf.c
> index 81781363af..7d773ab36d 100644
> --- a/sysdeps/ieee754/flt-32/e_remainderf.c
> +++ b/sysdeps/ieee754/flt-32/e_remainderf.c
> @@ -56,6 +56,9 @@ __ieee754_remainderf(float x, float p)
> }
> }
> GET_FLOAT_WORD(hx,x);
> + /* Make sure x is not -0. This can occur only when x = p
> + and rounding direction is towards negative infinity. */
> + if ((hx&0x7fffffff)==0) hx = 0;
> SET_FLOAT_WORD(x,hx^sx);
> return x;
> }
More information about the Libc-alpha
mailing list