-
-
Notifications
You must be signed in to change notification settings - Fork 30k
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
expm1 may incorrectly raise OverflowError on underflow #90176
Comments
If a C runtime's math functions set errno to ERANGE, we assume it is a valid underflow if fabs(result) < 1.0. However, because expm1 includes a -1.0, it underflows towards -1.0. This fails the above check, and so if a runtime's expm1() sets ERANGE we will raise a spurious OverflowError. |
It's a bit cheap and nasty, but I think we could simply replace the line:
in is_error with
perhaps with an explanatory comment. All we need to do is distinguish underflow from overflow, and 2.0 is still clearly a _long_ way away from any overflow boundary. It would be good to have a test that would trigger the behaviour, too. |
I presume this is also worth an upstream report? Setting ERANGE on a result that's close to -1.0 is rather questionable. |
I considered just switching to <2.0, but wasn't sure if I would be breaking some other unspoken behaviour there. But you're right, it's really just detecting underflow vs. overflow, so that's a much simpler way to check. I've filed the upstream report. I suspect the errno is coming from the exp() call within the expm1() implementation, so it's underflowing towards 0.0 and then subtracting 1. |
I've also got no idea how to write a test for this, given that it's a very thin wrapper around a platform's C runtime library. Our existing test discovered when the library changed behaviour to start setting errno, which is probably the best we can do. |
Yep, that's fine. All I want is that at least one particular value that caused the spurious OverflowError is in the test suite somewhere, but it sounds as though that's already the case. I'd imagine that one of these two testcases should be enough to trigger it: cpython/Lib/test/math_testcases.txt Lines 495 to 496 in 44b0e76
|
Lines 500-504 are the ones that trigger it. Apparently there are no tests in that file for straight exp(), but the equivalent tests for those would return 0.0 and suppress ERANGE too. |
Ah, right. Thanks.
Yes - that file was mostly written to give good coverage for places where we'd written our own implementations rather than simply wrapping an existing libm function, though I think we've now reverted to using the libm expm1 in all cases. |
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
The text was updated successfully, but these errors were encountered: