New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Math.Pow does not follow IEEE 754 for all inputs #7511
Comments
@dcwuser are you interested in getting cc'd on issues of such type? you did work in CoreFX to improve our handling of math edge cases. |
Thanks @danmosemsft, yes I am interested. Again, here is the spec: https://www.csee.umbc.edu/~tsimo1/CMSC455/IEEE-754-2008.pdf. The special cases of pow are listed on page 44. Spec ViolationsThe bug filer doesn't say which specific cases he believes applies and are violated, so I'm going to try to whittle it down to specifics. Presumably the pown and powr cases are irrelevant, since we don't have those functions. I'm going to interpret "signals the invalid operation exception" as "return NaN", since that's what we do elsewhere and the spec says "the default result of an operation that signals the invalid operation exception shall be a quiet NaN". And I'm going to interpret "signals the divideByZero exception" to mean nothing at all, since those cases actually specify a return value and again, that's what we do elsewhere. Given all that, here are the three cases we violate: P: We say Pow(-1, ±∞) = NaN, spec says 1. ConsiderationsP arises by regarding infinities as even integers, presumably because all sufficiently big representable FP numbers are even integers. Of course, the counter-argument is that it isn't true that all sufficiently big real numbers are even integers, and it's real numbers that we are trying to represent here, so we shouldn't elevate properties that arise from the vagaries of the FP representation into definitive truths. This counter-argument is made slightly weaker, though, by the fact that we do respect Pow(-0, −∞) = +∞, which also is only true if we regard infinities as even integers. Q and R arise from the principal that, if f(x) has a known, constant value c for all x != NaN, we should return that value for x = NaN, too. The idea is that NaN means "this is some real number, I just wasn't able to figure out which one", so if it doesn't matter which real number x was, we should swallow the NaN. One counter-argument is theoretical: NaN doesn't always mean that; for example, the NaN we get from taking the square root of a negative number actually means that the result is complex, and f(x) for complex x may well behave differently than for real x. An even better counter-argument is practical: if we swallow NaN's, the user might never investigate the potentially problematic parts of his code that generated them. The Wikipedia article on NaN's (https://en.wikipedia.org/wiki/NaN#Function_definition) addresses this controversy:
Personally I favor the always-propogate-NaNs principal over the swallow-NaNs-when-possible principal, but I didn't sit on the spec committee. RecomendationsAs with issue #7510, the spec violations are real but are violations of debatable spec conventions rather than mathematical conventions or truths. If the fixes are easy, have no perf impact, and we have cycles, we should go ahead and fix them. Otherwise, we shouldn't worry too much about them. I regard the argument for P as better than the argument for Q and R, so if we are only going to do a partial fix that's the one I would pick. |
Only one area path label please (avoids double counting in reports). |
Sorry for the delayed response here, but I listed all three because of the 'special' considerations for each function. We definitely don't implement That being said, since the current
We are definitely "implementing" |
This is something we should add, but it is not required for 2.0 |
@AlexGhiondea, I actually already have a pr out that fixes this. We had incorrect special handling on classlibnative. |
Self-assigning since this is fixed by dotnet/coreclr#10295 |
Test fixes in corefx are still needed. Tests are now disabled against this issue. |
@stephentoub which issue are they disabled against? This one? |
@karelz, yes, this one. The PR is here: dotnet/corefx#17419 I have my own PR which improves the test coverage of Math and MathF in general here: dotnet/corefx#17217 I have already updated it to match the Math.Pow and Math.Atan2 fixes made on the CoreCLR side. After dotnet/corefx#17419 goes in, I can rebase and resolve the merge conflicts and should be able to get the tests re-enabled in short order. |
The PR to re-enable the tests is just awaiting final sign-off before it gets merged. All jobs are green and I independently validated that the jobs have been appropriately partitioned into new vs legacy tests so that they pass on netfx as well. |
Fixed with dotnet/corefx#17217 |
The IEEE 754 spec defines the following inputs as special:
For the pown function (integral exponents only):
For the pow function (integral exponents get special treatment):
For the powr function (derived by considering only exp(y * log(x))):
However, the current implementation does not return the correct values for a number of these inputs (especially around the handling of NaN).
The text was updated successfully, but these errors were encountered: