Pseudo-random numbers/PCG32: Difference between revisions

Content deleted Content added
m Add link
→‎{{header|Python}}: Add generator version.
Line 909: Line 909:


=={{header|Python}}==
=={{header|Python}}==

===Python: As class===
<lang python>mask64 = (1 << 64) - 1
<lang python>mask64 = (1 << 64) - 1
mask32 = (1 << 32) - 1
mask32 = (1 << 32) - 1
Line 955: Line 957:
for i in range(100_000):
for i in range(100_000):
hist[int(random_gen.next_float() *5)] += 1
hist[int(random_gen.next_float() *5)] += 1
print(hist)</lang>

{{out}}
<pre>2707161783
2068313097
3122475824
2211639955
3215226955
{0: 20049, 1: 20022, 2: 20115, 3: 19809, 4: 20005}</pre>

===Python: As generator===
(Must divide int by 1 << 32 to get float values).

<lang python>mask64 = (1 << 64) - 1
mask32 = (1 << 32) - 1
CONST = 6364136223846793005


def pcg32(seed_state=None, seed_sequence=None):
def next_int():
"return random 32 bit unsigned int"
nonlocal state, inc

state, xorshifted, rot = (((state * CONST) + inc) & mask64,
(((state >> 18) ^ state) >> 27) & mask32,
(state >> 59) & mask32)
answer = (((xorshifted >> rot) | (xorshifted << ((-rot) & 31)))
& mask32)
return answer

# Seed
state = inc = 0
if all(type(x) == int for x in (seed_state, seed_sequence)):
inc = ((seed_sequence << 1) | 1) & mask64
next_int()
state += seed_state
next_int()

while True:
yield next_int()


if __name__ == '__main__':
from itertools import islice

for i in islice(pcg32(42, 54), 5):
print(i)
hist = {i:0 for i in range(5)}
for i in islice(pcg32(987654321, 1), 100_000):
hist[int(i / (1 << 32) * 5)] += 1
print(hist)</lang>
print(hist)</lang>