Fix roundoff bugs in prevpow
/nextpow
#45067
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR fixes a bug where
prevpow(2.0,prevfloat(1024.0)) == 1024.0
and a matching bug fornextpow
. The previous implementation didn't cover all the possible cases of roundoff in the logarithm, (eg: didn't consider thatlog(2.0,prevfloat(1024.0))==10.0
, whichfloor
s to 10 instead of the mathematically correct 9).It also adds a
DomainError
in the case that the input is beyond the range of the returned type. Previously, for example,prevpow(Int8(4),200) == 0
was a silent incorrect result. The only exception is a base of2::Integer
for anyInteger
, which has its own special case. One could technically only throw an error when the result is out-of-range (eg,prevpow(Int8(4),200)
could correctly return64
even though200>typemax(Int8)
), but that was more complicated (and the previous behavior was to return0
).It also adds an
OverflowError
tonextpow
when the result is not representable. Previously,nextpow(Int8(4),65) == 0
.The added errors could be considered breaking. It's hard to imagine anybody was intentionally using this behavior, but they could be split off if controversial.