diff options
author | Kevin Sheppard <kevin.k.sheppard@gmail.com> | 2019-09-13 23:04:15 +0100 |
---|---|---|
committer | Kevin Sheppard <kevin.k.sheppard@gmail.com> | 2019-09-14 21:35:15 +0100 |
commit | 5e148ad95f6135382ee5adf999a38342b792ae06 (patch) | |
tree | dc3602426c41e68e32a2ffda27cbfe0b015acbeb | |
parent | 31ffdecf07d18ed4dbb66b171cb0f998d4b190fa (diff) | |
download | numpy-5e148ad95f6135382ee5adf999a38342b792ae06.tar.gz |
BUG: Fix randint when range is 2**32
Fix randint to use 32-bit path when range is exactly 2**32
closes #14189
-rw-r--r-- | doc/release/upcoming_changes/14501.improvement.rst | 6 | ||||
-rw-r--r-- | numpy/random/src/distributions/distributions.c | 4 | ||||
-rw-r--r-- | numpy/random/tests/test_randomstate_regression.py | 11 |
3 files changed, 19 insertions, 2 deletions
diff --git a/doc/release/upcoming_changes/14501.improvement.rst b/doc/release/upcoming_changes/14501.improvement.rst new file mode 100644 index 000000000..f397ecccf --- /dev/null +++ b/doc/release/upcoming_changes/14501.improvement.rst @@ -0,0 +1,6 @@ +`numpy.random.randint` produced incorrect value when the range was ``2**32`` +---------------------------------------------------------------------------- +The implementation introduced in 1.17.0 had an incorrect check when +determining whether to use the 32-bit path or the full 64-bit +path that incorrectly redirected random integer generation with a high - low +range of ``2**32`` to the 64-bit generator. diff --git a/numpy/random/src/distributions/distributions.c b/numpy/random/src/distributions/distributions.c index 65257ecbf..f8d6b9dc5 100644 --- a/numpy/random/src/distributions/distributions.c +++ b/numpy/random/src/distributions/distributions.c @@ -1478,7 +1478,7 @@ uint64_t random_bounded_uint64(bitgen_t *bitgen_state, uint64_t off, uint64_t rng, uint64_t mask, bool use_masked) { if (rng == 0) { return off; - } else if (rng < 0xFFFFFFFFUL) { + } else if (rng <= 0xFFFFFFFFUL) { /* Call 32-bit generator if range in 32-bit. */ if (use_masked) { return off + buffered_bounded_masked_uint32(bitgen_state, rng, mask, NULL, @@ -1592,7 +1592,7 @@ void random_bounded_uint64_fill(bitgen_t *bitgen_state, uint64_t off, for (i = 0; i < cnt; i++) { out[i] = off; } - } else if (rng < 0xFFFFFFFFUL) { + } else if (rng <= 0xFFFFFFFFUL) { uint32_t buf = 0; int bcnt = 0; diff --git a/numpy/random/tests/test_randomstate_regression.py b/numpy/random/tests/test_randomstate_regression.py index 29870534a..ae92319c4 100644 --- a/numpy/random/tests/test_randomstate_regression.py +++ b/numpy/random/tests/test_randomstate_regression.py @@ -181,3 +181,14 @@ class TestRegression(object): assert c.dtype == np.dtype(int) c = np.random.choice(10, replace=False, size=2) assert c.dtype == np.dtype(int) + + @pytest.mark.skipif(np.iinfo('l').max < 2**32, + reason='Cannot test with 32-bit C long') + def test_randint_117(self): + # GH 14189 + random.seed(0) + expected = np.array([2357136044, 2546248239, 3071714933, 3626093760, + 2588848963, 3684848379, 2340255427, 3638918503, + 1819583497, 2678185683], dtype='int64') + actual = random.randint(2**32, size=10) + assert_array_equal(actual, expected)
\ No newline at end of file |