File 20049-pcg-emu-int128.patch of Package python3-numpy.37339

From 401b26e880117ae5bc72b84a7fd267e999f99aa1 Mon Sep 17 00:00:00 2001
From: Kevin Sheppard <kevin.k.sheppard@gmail.com>
Date: Wed, 6 Oct 2021 09:45:21 +0100
Subject: [PATCH] BUG: Correct incorrect advance in PCG with emulated int128

Correct incorrect implemetation of carry in PCG64 and PCG64DXSM
when advancing more than 2**64 steps

closes #20048
---
 doc/release/upcoming_changes/20049.change.rst |    5 +++++
 numpy/random/src/pcg64/pcg64.c                |    3 +--
 numpy/random/tests/test_direct.py             |   22 ++++++++++++++++++++++
 3 files changed, 28 insertions(+), 2 deletions(-)
 create mode 100644 doc/release/upcoming_changes/20049.change.rst

--- /dev/null
+++ b/doc/release/upcoming_changes/20049.change.rst
@@ -0,0 +1,5 @@
+Corrected ``advance`` in ``PCG64DSXM`` and ``PCG64``
+----------------------------------------------------
+Fixed a bug in the ``advance`` method of ``PCG64DSXM`` and ``PCG64``. The bug only
+affects results when the step was larger than :math:`2^{64}` on platforms
+that do not support 128-bit integers(e.g., Windows and 32-bit Linux).
--- a/numpy/random/src/pcg64/pcg64.c
+++ b/numpy/random/src/pcg64/pcg64.c
@@ -105,8 +105,7 @@ pcg128_t pcg_advance_lcg_128(pcg128_t st
     cur_plus = pcg128_mult(pcg128_add(cur_mult, PCG_128BIT_CONSTANT(0u, 1u)),
                             cur_plus);
     cur_mult = pcg128_mult(cur_mult, cur_mult);
-    delta.low >>= 1;
-    delta.low += delta.high & 1;
+    delta.low = (delta.low >> 1) | (delta.high << 63);
     delta.high >>= 1;
   }
   return pcg128_add(pcg128_mult(acc_mult, state), acc_plus);
--- a/numpy/random/tests/test_direct.py
+++ b/numpy/random/tests/test_direct.py
@@ -351,6 +351,17 @@ class TestPCG64(Base):
         assert val_neg == val_pos
         assert val_big == val_pos
 
+    def test_advange_large(self):
+        rs = Generator(self.bit_generator(38219308213743))
+        pcg = rs.bit_generator
+        state = pcg.state["state"]
+        initial_state = 287608843259529770491897792873167516365
+        assert state["state"] == initial_state
+        pcg.advance(sum(2**i for i in (96, 64, 32, 16, 8, 4, 2, 1)))
+        state = pcg.state["state"]
+        advanced_state = 135275564607035429730177404003164635391
+        assert state["state"] == advanced_state
+
 
 class TestMT19937(Base):
     @classmethod
@@ -387,6 +398,17 @@ class TestMT19937(Base):
         actual = rs.integers(2 ** 16)
         assert_equal(actual, desired)
 
+    def test_advange_large(self):
+        rs = Generator(self.bit_generator(38219308213743))
+        pcg = rs.bit_generator
+        state = pcg.state
+        initial_state = 287608843259529770491897792873167516365
+        assert state["state"]["state"] == initial_state
+        pcg.advance(sum(2**i for i in (96, 64, 32, 16, 8, 4, 2, 1)))
+        state = pcg.state["state"]
+        advanced_state = 277778083536782149546677086420637664879
+        assert state["state"] == advanced_state
+
 
 class TestSFC64(Base):
     @classmethod
openSUSE Build Service is sponsored by