fmod nan_mix usage
Bruce Evans
brde at optusnet.com.au
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.
Bruce
More information about the freebsd-numerics
mailing list