Closes #14591: Random.jumpahead could produce an invalid MT state on 64-bit machines.
This commit is contained in:
parent
9848d812a3
commit
e0afb72402
|
@ -57,6 +57,14 @@ class TestBasicOps(unittest.TestCase):
|
|||
self.assertRaises(TypeError, self.gen.jumpahead) # needs an arg
|
||||
self.assertRaises(TypeError, self.gen.jumpahead, 2, 3) # too many
|
||||
|
||||
def test_jumpahead_produces_valid_state(self):
|
||||
# From http://bugs.python.org/issue14591.
|
||||
self.gen.seed(199210368)
|
||||
self.gen.jumpahead(13550674232554645900)
|
||||
for i in range(500):
|
||||
val = self.gen.random()
|
||||
self.assertLess(val, 1.0)
|
||||
|
||||
def test_sample(self):
|
||||
# For the entire allowable range of 0 <= k <= N, validate that
|
||||
# the sample is of the correct length and contains only unique items
|
||||
|
|
|
@ -75,6 +75,9 @@ Core and Builtins
|
|||
Library
|
||||
-------
|
||||
|
||||
- Issue #14591: Fix bug in Random.jumpahead that could produce an invalid
|
||||
Mersenne Twister state on 64-bit machines.
|
||||
|
||||
- Issue #5346: Preserve permissions of mbox, MMDF and Babyl mailbox
|
||||
files on flush().
|
||||
|
||||
|
|
|
@ -400,7 +400,7 @@ random_jumpahead(RandomObject *self, PyObject *n)
|
|||
long i, j;
|
||||
PyObject *iobj;
|
||||
PyObject *remobj;
|
||||
unsigned long *mt, tmp;
|
||||
unsigned long *mt, tmp, nonzero;
|
||||
|
||||
if (!PyInt_Check(n) && !PyLong_Check(n)) {
|
||||
PyErr_Format(PyExc_TypeError, "jumpahead requires an "
|
||||
|
@ -427,8 +427,23 @@ random_jumpahead(RandomObject *self, PyObject *n)
|
|||
mt[j] = tmp;
|
||||
}
|
||||
|
||||
for (i = 0; i < N; i++)
|
||||
nonzero = 0;
|
||||
for (i = 1; i < N; i++) {
|
||||
mt[i] += i+1;
|
||||
mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
|
||||
nonzero |= mt[i];
|
||||
}
|
||||
|
||||
/* Ensure the state is nonzero: in the unlikely event that mt[1] through
|
||||
mt[N-1] are all zero, set the MSB of mt[0] (see issue #14591). In the
|
||||
normal case, we fall back to the pre-issue 14591 behaviour for mt[0]. */
|
||||
if (nonzero) {
|
||||
mt[0] += 1;
|
||||
mt[0] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
|
||||
}
|
||||
else {
|
||||
mt[0] = 0x80000000UL;
|
||||
}
|
||||
|
||||
self->index = N;
|
||||
Py_INCREF(Py_None);
|
||||
|
|
Loading…
Reference in New Issue