fmod nan_mix usage

Bruce Evans brde at
Mon Jul 23 19:54:47 UTC 2018

On Mon, 23 Jul 2018, enh via freebsd-numerics wrote:

> the recent change from
>  return (x*y)/(x*y);
> to
>  return nan_mix(x, y)/nan_mix(x, y);
> in e_fmod.c broke some of our unit tests. for example, fmod(3.f, 0.f) in
> one of the VM tests.

This is a bug in my change.

nan_mix(x, y) does essentially x+y, but here essentially x*y is needed so
that y = 0 gives 0 unless x is NaN.  In the example, adding gives 3 instead
of 0, so the final result is 1 instead of 0.0/0.0 = NaN.

The log message mentions avoiding this problem in s_ccosh[fl].c and
s_sinh[fl].c.  This list was supposed have all special cases.

Unfortunately, this seems to prevent use of a single macro.  I will try
using a 2 macros with 1 using sums and the other products.  The non-broken
cases converted sums to sums.

> bionic/tests/math_test.cpp:(784) Failure in test
> math_h_force_long_double.fmod
> Value of: isnan(fmod(3.0, 0.0))
>  Actual: false
> Expected: true
> math_h_force_long_double.fmod exited with exitcode 1.
> [  FAILED  ] math_h_force_long_double.fmodf (13 ms)
> bionic/tests/math_test.cpp:(798) Failure in test
> math_h_force_long_double.fmodf
> Value of: isnanf(fmodf(3.0f, 0.0f))
>  Actual: false
> Expected: true
> math_h_force_long_double.fmodf exited with exitcode 1.
> [  FAILED  ] math_h_force_long_double.fmodl (12 ms)
> bionic/tests/math_test.cpp:(812) Failure in test
> math_h_force_long_double.fmodl
> Value of: isnanl(fmodl(3.0L, 0.0L))
>  Actual: false
> Expected: true

Do you have a lot of special tests like this?  I mostly use generic tests
that don't assert any particular result, but compare the results in
different precisions.  I apparently changed all precisions to be
consistently wrong at the same time.

> it looks like e_remainder.c might have the same issue, but Android's tests
> didn't catch that :-( i'll improve the tests...

Indeed.  Also remquo* and ctanh* :-(.  ctanh* should be more like csinh*
and ccosh*, and it was.

The only other complicated case seems to be hypot[fl]().  This subtracts
instead of adds, since it wants to convert Inf-Inf to NaN.


More information about the freebsd-numerics mailing list