-
-
Notifications
You must be signed in to change notification settings - Fork 31.7k
Left shift of zero allocates memory #72057
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
Comments
Using a random testing system to compare Python long behavior to GMP (via gmpy2), I notice that in a low-memory situation (created by allocating many large integers in both Python and GMP), a left-shift of 0 by large number of bytes:
... Auto-generated test is attached, though probably not needed to understand the issue. File is not minimized, since I suspect most of the code is just to choke memory, and you probably need the right memory config to replay, but it shows the basic idea. For more info, see https://github.com/agroce/tstl/tree/master/examples/gmpy2 |
(to clarify: 0 << N allocates memory (which can fail, raising MemoryError) based on N. GMP simply returns 0 for any N. |
AND, right shift >> does not allocate memory, so there is a lack of symmetry that indicates the optimization might be desired. see https://github.com/agroce/tstl/tree/master/examples/gmpy2/leftshiftalloc.py to compare behaviors, but these are depending on memory size, this was generated on MacBook Pro OS X Yosemite machine with 16GB) |
Are you saying that Python aborts, or that it raises a MemoryError? |
Allocates, then fails to perform the operation (with MemoryError). Neither a crash nor resource allocation, precisely, just fails to carry out operation GMP integers can do under the same circumstances. |
If it raises a MemoryError, then it is working as designed. Returning 0 would be the wrong answer, so I don't understand why GMP would do that. |
Wait, when you talk about 'long', are you using that in the C sense? Because python long integers are size-limited only by the amount of memory. |
I mean a Python long. GMP mpz (via gmpy2) is supposed to be "drop-in" replacement, but it's choice to handle 0 << N even if N is too large to allocate (since you get back a 1-bit number, 0) seems reasonable, if not required for correct behavior. If this is by design, it seems reasonable (if the zero check is considered too expensive, for example). |
Oh, my apologies. I was not reading your message with enough attention, you are only talking about the zero case. A check for zero would not be crazy, and I think there are enough operations involved in left shift that the performance impact would not be measurable. I'll leave that to the math experts, though. |
Also applies to 3.x. Working on a fix. |
Here's a patch against 3.6. I think this probably shouldn't be changed for 3.5, but it may be worth backporting the fix to 2.7. |
Updated patch, breaking out the implementation-specific tests into their own method. (Thanks, Serhiy!) |
LGTM. |
New changeset 09fa42818cf8 by Mark Dickinson in branch 'default': |
New changeset 58ea646ef657 by Mark Dickinson in branch '2.7': |
Fixed for 2.7 and 3.6. Closing. |
New changeset 2b190bfd9ab4 by Benjamin Peterson in branch '2.7': |
Gah. Sorry about that. Thanks for the refleak fix, Benjamin. |
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: