-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
bpo-29816: Shift operation now has less opportunity to raise OverflowError. #680
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
bpo-29816: Shift operation now has less opportunity to raise OverflowError. #680
Conversation
…Error. ValueError always is raised rather than OverflowError for negative counts. Shifting zero with non-negative count always returns zero.
@serhiy-storchaka, thanks for your PR! By analyzing the history of the files in this pull request, we identified @mdickinson, @tim-one and @brettcannon to be potential reviewers. |
Objects/longobject.c
Outdated
return NULL; | ||
if (shiftby >= 0) { | ||
wordshift = shiftby / PyLong_SHIFT; | ||
loshift = shiftby - wordshift * PyLong_SHIFT; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not loshift = shiftby % PyLong_SHIFT;
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Left shift uses such code. I suppose this is because multiplication and substraction are faster than the "%" operation. If there is a reason to use it for left shift, there is a reason to use it for right shift.
The new code for left and right shifts are almost exact duplicates (there is additional optimization for right shift, but it is not very important and can be omitted). Is it worth to extract it in the helper function?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose this is because multiplication and substraction are faster than the "%" operation.
This seems unlikely to me. In particular, I'd expect an optimising compiler to be able to recognise and do a good job of optimising the pair shiftby / PyLong_SHIFT
and shiftby % PyLong_SHIFT
if they appear next to each other in code. Rewriting the %
would likely make it harder for the compiler to recognise.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it worth to extract it in the helper function?
That sounds reasonable to me, if you want to do it; if you don't, that also sounds reasonable to me. :-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks okay to me, but if feels a bit convoluted and hard to read / hard to verify. Why not use PyLong arithmetic in the overflow case, for example using divrem1
to extract the number of words / number of bits to shift?
ValueError always is raised rather than OverflowError for negative counts.
Shifting zero with non-negative count always returns zero.