I need to translate ILGPU's XorShift128Plus class into Python. First, I have written a unit test for the C# version: using Microsoft.VisualStudio.TestTools.UnitTesting; using ILGPU.Algorithms.Random; using System; namespace MyTests { [TestClass] public class XorShift128PlusTests { [TestMethod] public void TestInitialization() { var rng = new XorShift128Plus(123456789UL, 987654321UL); Assert.AreEqual(123456789UL, rng.State0); Assert.AreEqual(987654321UL, rng.State1); } [TestMethod] public void TestNextULong() { var rng = new XorShift128Plus(123456789UL, 987654321UL); var actual = rng.NextULong(); Assert.AreEqual(1035635210406904UL, actual); } [TestMethod] public void TestNextUInt() { var rng = new XorShift128Plus(123456789UL, 987654321UL); var actual = rng.NextUInt(); Assert.AreEqual(2631329311, actual); } [TestMethod] public void TestNext() { var rng = new XorShift128Plus(123456789UL, 987654321UL); var actual = rng.Next(); Assert.AreEqual(483845663, actual); } [TestMethod] public void TestNextLong() { var rng = new XorShift128Plus(123456789UL, 987654321UL); var actual = rng.NextLong(); Assert.AreEqual(1035635210406904L, actual); } [TestMethod] public void TestNextFloat() { var rng = new XorShift128Plus(123456789UL, 987654321UL); var value = rng.NextFloat(); var actual = value.Trim(6); var expected = 0.0001122839f.Trim(6); float tolerance = 1e-7f; // Small allowable error due to float limitations Assert.IsTrue(Math.Abs(expected - actual) < tolerance, $"Expected {expected}, but got {actual}"); } [TestMethod] public void TestNextDouble() { var rng = new XorShift128Plus(123456789UL, 987654321UL); var actual = rng.NextDouble(); Assert.AreEqual(0.000112283794502565.Trim(15), actual.Trim(15)); } [TestMethod] public void TestShiftPeriod() { var rng = new XorShift128Plus(123456789UL, 987654321UL); var oldState0 = rng.State0; var oldState1 = rng.State1; rng.ShiftPeriod(10); Assert.IsTrue(rng.State0 != oldState0 || rng.State1 != oldState1); } [TestMethod] public void TestNextProvider() { var rng = new XorShift128Plus(123456789UL, 987654321UL); var newRng = rng.NextProvider(); Assert.IsInstanceOfType(newRng, typeof(XorShift128Plus)); Assert.IsTrue(newRng.State0 != rng.State0 || newRng.State1 != rng.State1); } [TestMethod] public void TestCreateProvider() { var rng = new XorShift128Plus(123456789UL, 987654321UL); var newRng = rng.CreateProvider(new Random(42)); Assert.IsInstanceOfType(newRng, typeof(XorShift128Plus)); Assert.IsTrue(newRng.State0 > 0UL && newRng.State1 > 0UL); } [TestMethod] public void TestEquality() { var rng1 = new XorShift128Plus(123456789UL, 987654321UL); var rng2 = new XorShift128Plus(123456789UL, 987654321UL); var rng3 = new XorShift128Plus(111111111UL, 222222222UL); Assert.AreEqual(rng1, rng2); Assert.AreNotEqual(rng1, rng3); } [TestMethod] public void TestHash() { var rng1 = new XorShift128Plus(123456789UL, 987654321UL); var rng2 = new XorShift128Plus(123456789UL, 987654321UL); Assert.AreEqual(rng1.GetHashCode(), rng2.GetHashCode()); } [TestMethod] public void TestToString() { var rng = new XorShift128Plus(123456789UL, 987654321UL); Assert.AreEqual("[123456789, 987654321]", rng.ToString()); } } } public static class DoubleTrimmer { public static double Trim(this double value, int decimal_places) { return Math.Round(value, decimal_places); } public static double Clamp(this double value, double min, double max) { if (value < min) return min; if (value > max) return max; return value; } public static float Trim(this float value, int decimal_places) { float factor = (float)Math.Pow(10f, decimal_places); return (float)Math.Round(value * factor) / factor; } public static float Clamp(this float value, float min, float max) { if (value < min) return min; if (value > max) return max; return value; } public static decimal Trim(this decimal value, int decimal_places) { return Math.Round(value, decimal_places); } public static decimal Clamp(this decimal value, decimal min, decimal max) { if (value < min) return min; if (value > max) return max; return value; } } Then I have translated the C# class into a Python class: import random import struct class XorShift128Plus: """ Implements a simple and fast xor-shift RNG. """ def __init__(self, state0: int, state1: int): if state0 == 0 and state1 == 0: raise ValueError("State must not be zero") self.state0 = state0 self.state1 = state1 @staticmethod def create(seed_random: random.Random = None): if seed_random is None: seed_random = random.Random() state0 = (seed_random.randint(1, 0x7FFFFFFF) << 32) | seed_random.randint(0, 0xFFFFFFFF) state1 = (seed_random.randint(0, 0xFFFFFFFF) << 32) | seed_random.randint(0, 0xFFFFFFFF) return XorShift128Plus(state0, state1) def next_ulong(self) -> int: x = self.state0 y = self.state1 self.state0 = y x ^= (x << 23) & 0xFFFFFFFFFFFFFFFF self.state1 = x ^ y ^ ((x >> 17) & 0xFFFFFFFFFFFFFFFF) ^ ((y >> 26) & 0xFFFFFFFFFFFFFFFF) return (self.state1 + y) & 0xFFFFFFFFFFFFFFFF def next_uint(self) -> int: return self.next_ulong() & 0xFFFFFFFF def next(self) -> int: return self.next_uint() & 0x7FFFFFFF def next_long(self) -> int: return struct.unpack("q", struct.pack("Q", self.next_ulong()))[0] def next_float(self) -> float: return self.next_long() * (1.0 / (1 << 63)) def next_double(self) -> float: return self.next_long() * (1.0 / (1 << 63)) def shift_period(self, shift: int): local_rng = XorShift128Plus.create() for _ in range(shift): local_rng.next_ulong() self.state0 = local_rng.next_ulong() self.state1 = local_rng.next_ulong() def next_provider(self): return XorShift128Plus(self.next_ulong(), self.next_ulong()) def create_provider(self, other_random): return XorShift128Plus(abs(other_random.next_long()) + 1, abs(other_random.next_long()) + 1) def __eq__(self, other): if not isinstance(other, XorShift128Plus): return False return self.state0 == other.state0 and self.state1 == other.state1 def __hash__(self): return hash((self.state0, self.state1)) def __repr__(self): return f"XorShift128Plus({self.state0}, {self.state1})" Then, I have translated the C# version of the unit-test into a PyTest module. import unittest from XorShift128Plus import XorShift128Plus class TestXorShift128Plus(unittest.TestCase): def test_initialization(self): rng = XorShift128Plus(123456789, 987654321) self.assertEqual(rng.state0, 123456789) self.assertEqual(rng.state1, 987654321) def test_next_ulong(self): rng = XorShift128Plus(123456789, 987654321) actual = rng.next_ulong() self.assertEqual(actual, 1035635210406904) def test_next_uint(self): rng = XorShift128Plus(123456789, 987654321) actual = rng.next_uint() self.assertEqual(actual, 2631329311) def test_next(self): rng = XorShift128Plus(123456789, 987654321) actual = rng.next() self.assertEqual(actual, 483845663) def test_next_long(self): rng = XorShift128Plus(123456789, 987654321) actual = rng.next_long() self.assertEqual(actual, 1035635210406904) def test_next_float(self): rng = XorShift128Plus(123456789, 987654321) value = rng.next_float() actual = round(value, 6) expected = round(0.0001122839, 6) print(f"Original: {value}") print(f"Rounded : {actual}") print(f"Expected: {expected}") tolerance = 1e-7 # Small allowable error due to float limitations self.assertTrue(abs(expected - actual) < tolerance, f"Expected {expected}, but got {actual}") def test_next_double(self): rng = XorShift128Plus(123456789, 987654321) actual = rng.next_double() self.assertEqual(round(actual, 15), round(0.000112283794502565, 15)) def test_shift_period(self): rng = XorShift128Plus(123456789, 987654321) old_state0, old_state1 = rng.state0, rng.state1 rng.shift_period(10) self.assertTrue(rng.state0 != old_state0 or rng.state1 != old_state1) def test_next_provider(self): rng = XorShift128Plus(123456789, 987654321) new_rng = rng.next_provider() self.assertIsInstance(new_rng, XorShift128Plus) self.assertTrue(new_rng.state0 != rng.state0 or new_rng.state1 != rng.state1) def test_create_provider(self): rng = XorShift128Plus(123456789, 987654321) new_rng = rng.create_provider(rng) self.assertIsInstance(new_rng, XorShift128Plus) self.assertTrue(new_rng.state0 > 0 and new_rng.state1 > 0) def test_equality(self): rng1 = XorShift128Plus(123456789, 987654321) rng2 = XorShift128Plus(123456789, 987654321) rng3 = XorShift128Plus(111111111, 222222222) self.assertEqual(rng1, rng2) self.assertNotEqual(rng1, rng3) def test_hash(self): rng1 = XorShift128Plus(123456789, 987654321) rng2 = XorShift128Plus(123456789, 987654321) self.assertEqual(hash(rng1), hash(rng2)) def test_repr(self): rng = XorShift128Plus(123456789, 987654321) self.assertEqual(repr(rng), "XorShift128Plus(123456789, 987654321)") if __name__ == "__main__": unittest.main() Now, the issue is, Python's test_next() and test_next_uint() are failing: ....F 483845663 != 483740664 Expected :483740664 Actual :483845663 <Click to see difference> self = <RefPythonCode.unit_test_for_XorShift128Plus.TestXorShift128Plus testMethod=test_next> first = 483740664, second = 483845663, msg = None def _patched_equals(self, first, second, msg=None): try: > old(self, first, second, msg) E AssertionError: 483740664 != 483845663 C:\Program Files\JetBrains\PyCharm 2018.3.7\helpers\pycharm\teamcity\diff_tools.py:32: AssertionError During handling of the above exception, another exception occurred: self = <RefPythonCode.unit_test_for_XorShift128Plus.TestXorShift128Plus testMethod=test_next> def test_next(self): rng = XorShift128Plus(123456789, 987654321) actual = rng.next() > self.assertEqual(actual, 483845663) unit_test_for_XorShift128Plus.py:25: ..Original: 0.00011228379450256478 Rounded : 0.000112 Expected: 0.000112 ..F 2631329311 != 2631224312 Expected :2631224312 Actual :2631329311 <Click to see difference> self = <RefPythonCode.unit_test_for_XorShift128Plus.TestXorShift128Plus testMethod=test_next_uint> first = 2631224312, second = 2631329311, msg = None def _patched_equals(self, first, second, msg=None): try: > old(self, first, second, msg) E AssertionError: 2631224312 != 2631329311 C:\Program Files\JetBrains\PyCharm 2018.3.7\helpers\pycharm\teamcity\diff_tools.py:32: AssertionError During handling of the above exception, another exception occurred: self = <RefPythonCode.unit_test_for_XorShift128Plus.TestXorShift128Plus testMethod=test_next_uint> def test_next_uint(self): rng = XorShift128Plus(123456789, 987654321) actual = rng.next_uint() > self.assertEqual(actual, 2631329311) unit_test_for_XorShift128Plus.py:20: ... How can I make the Python version match the output with the C# version? Continue reading...