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
random.getrandbits is limited to 2**31-1 bits on 64-bit Windows #71259
Comments
The C implementation of The argument parsing code in Since the number of bits is directly related to how much memory we need to allocate (in the non-fast case), I think I'm attaching a very simple patch that changes the types of the relevant variables and the format code in the call to This issue doesn't effect the pure Python implementation of For convenience, here's the contents of the very short patch (which I'll also attach): diff --git a/Modules/_randommodule.c b/Modules/_randommodule.c
index fd6b230..3bf564f 100644
--- a/Modules/_randommodule.c
+++ b/Modules/_randommodule.c
@@ -348,12 +348,12 @@ random_setstate(RandomObject *self, PyObject *state)
static PyObject *
random_getrandbits(RandomObject *self, PyObject *args)
{
- int k, i, words;
+ Py_ssize_t k, i, words;
PY_UINT32_T r;
PY_UINT32_T *wordarray;
PyObject *result;
if (k <= 0) { |
In fact it is, the limitation applies to 64bit Linux too. (tested in CPython 3.5.1) |
Since the downstream calls to PyMem_Malloc and _PyLong_FromByteArray both accept size_t for their sizing, there isn't a problem there. That said, I think the current limitation nicely protects us from harm. If you were to run getrandbits(2**60) it would take a long time, eat all your memory, trigger swaps until your harddrive was full, and you wouldn't be able to break out of the tight loop with a keyboard interrupt. Even with the current limit, the resultant int object is ridiculously big in a way that is awkward to manipulate after it is created (don't bother trying to print it, jsonify it, or doing any interesting math it). Also, if a person wants a lot of bits, it is effortless to make repeated calls getrandbits() using the current API. Doing so would likely improve their code and be a better design (consuming bits as generated rather than creating them all at once and extracting them later). In short, just because we can do it, doesn't mean we should. |
@rhettinger, agree that very large ints in this case aren't going to give very usable results. On the other hand, this limit isn't imposed elsewhere (you can power-of operator to create bigger numbers). Nevertheless this isn't going to give good/usable performance. ---- Might having a method added to |
There are a number of places in the language with these limits. In general, we're opening them up to wider limits if there are valid use cases and if it doesn't immediately shoot you in the foot like it does here. Practicality is a reasonable design consideration. Mitigation of harm is also reasonable design consideration. Foolish consistently is, well, you know how the saying goes :-)
It isn't needed. As far as I know, there has never been a user request for this functionality nor a presentation of use cases that benefit it. The API is already bloated and we already have one way to do it with int.to_bytes(). Also, we should keep this tracker entry focused on the OP's report and not meander. |
The only case I know that would benefit is generating random data for tests. On my computer generating 2*28 bits with getrandbits() takes 2 sec (including 1 sec for converting from bytes to int), plus 1.4 sec for converting from int to bytes. Special API would speed up generating random bytes by 3.4 times. I would request for this functionality, but I don't want to clutter the API. As for getrandbits.diff, I think that we should follow the principle "we're all consenting adults here". |
Sorry Steven, I'm going to mark this as rejected on the grounds that it is likely to do more harm than good. We could in fact make the range larger but it easily creates terrible effects (encouraging bad design and creating a non-interruptable, long-running, total-memory-filling call). While we do allow |
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: