raspberrypi / pico-sdk

BSD 3-Clause "New" or "Revised" License
3.69k stars 917 forks source link

log2, log10, acosh and tgamma don't return NaN when they should #1256

Open dpgeorge opened 1 year ago

dpgeorge commented 1 year ago

The following functions evaluated at the given points return a finite or infinite result when then should return Nan:

I'm not sure exactly what the policy is for domain errors, but when PICO_FLOAT_PROPAGATE_NANS is enabled a lot of other cases of NaN are handled, so one would expect the above to also be handled correctly.

Edit: possibly also the following:

kilograham commented 1 year ago

yes, there seems to be a mixture - initially the policy was intended to be PROPAGATE_NANs should take NAN input to NAN output, but we clearly have code in some places to fix this.

I'm surprised log(-INFINITY) isn't listed...

can you point me at the test for this in MP

dpgeorge commented 1 year ago

tests/float/math_domain_special.py is the test.

That tests also see some strange behaviour of math.asinh(0) returning -0.0 when it should be 0.0, but I couldn't track that bug down because when I ran asinhf(0.0) in C code it returned 0.0 as expected.

dpgeorge commented 1 year ago

I'm surprised log(-INFINITY) isn't listed...

Surprisingly we don't have a test for this... I'm in the process of adding one but it seems that it does pass on rp2 because we handle math.log(x[, base]) differently to log2 and log10: log explicitly checks that it's argument is positive.

dpgeorge commented 1 year ago

To run the tests on MP:

$ cd tests
$ ./run-tests.py --target rp2 -d float

Then to see the diff of the expected (left) vs actual (right) results:

$ diff results/float_cmath_fun.py.exp results/float_cmath_fun.py.out 
113c113
< complex(-109.71, 55.602)
---
> complex(-109.72, 55.601)

$ diff results/float_math_domain.py.exp results/float_math_domain.py.out 
16c16
< sqrt(-inf) = ValueError
---
> sqrt(-inf) = -inf

$ diff results/float_math_domain_special.py.exp results/float_math_domain_special.py.out
7c7
< log2(-inf) = ValueError
---
> log2(-inf) = -inf
12c12
< log10(-inf) = ValueError
---
> log10(-inf) = -inf
26c26
< acosh(-1.0000) = ValueError
---
> acosh(-1.0000) = 0.0000
30c30
< acosh(-inf) = ValueError
---
> acosh(-inf) = inf
48c48
< gamma(-inf) = ValueError
---
> gamma(-inf) = inf

$ diff results/float_math_fun_special.py.exp results/float_math_fun_special.py.out
60c60
< asinh(0) = 0
---
> asinh(0) = -0

(The first one there is #1255.)