From ce339974e6f97fb3cc67cf1e2d45e5b3142e7c13 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Sat, 7 Dec 2024 18:41:45 +0800 Subject: [PATCH] update random --- benchmarks/dict_0.py | 4 ++++ src/modules/random.c | 20 ++++++++++++++------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/benchmarks/dict_0.py b/benchmarks/dict_0.py index 9637fac5..c36f81eb 100644 --- a/benchmarks/dict_0.py +++ b/benchmarks/dict_0.py @@ -18,3 +18,7 @@ missed = a['missed'] assert abs(existed - missed) < 10000 +rnd = random.Random(7) +assert rnd.randint(1, 100) == 16 +assert rnd.randint(1, 100) == 93 +assert rnd.randint(1, 100) == 22 \ No newline at end of file diff --git a/src/modules/random.c b/src/modules/random.c index 2137e245..e7c552ae 100644 --- a/src/modules/random.c +++ b/src/modules/random.c @@ -112,12 +112,14 @@ static uint64_t mt19937__next_uint64(mt19937* self) { return (uint64_t)mt19937__next_uint32(self) << 32 | mt19937__next_uint32(self); } -/* generates a random number on [0,1)-real-interval */ -static float mt19937__random(mt19937* self) { - return mt19937__next_uint32(self) * (1.0 / 4294967296.0); /* divided by 2^32 */ +static double mt19937__random(mt19937* self) { + // from cpython + uint32_t a = mt19937__next_uint32(self) >> 5; + uint32_t b = mt19937__next_uint32(self) >> 6; + return (a * 67108864.0 + b) * (1.0 / 9007199254740992.0); } -static float mt19937__uniform(mt19937* self, float a, float b) { +static double mt19937__uniform(mt19937* self, double a, double b) { if(a > b) { return b + mt19937__random(self) * (a - b); } return a + mt19937__random(self) * (b - a); } @@ -133,10 +135,16 @@ int64_t mt19937__randint(mt19937* self, int64_t a, int64_t b) { } static bool Random__new__(int argc, py_Ref argv) { - PY_CHECK_ARGC(1); mt19937* ud = py_newobject(py_retval(), py_totype(argv), 0, sizeof(mt19937)); mt19937__ctor(ud); - return true; + if(argc == 1) return true; + if(argc == 2) { + PY_CHECK_ARG_TYPE(1, tp_int); + py_i64 seed = py_toint(py_arg(1)); + mt19937__seed(ud, seed); + return true; + } + return TypeError("Random(): expected 0 or 1 arguments, got %d", argc - 1); } static bool Random_seed(int argc, py_Ref argv) {