Pseudo-random numbers/PCG32: Difference between revisions

m
m (→‎{{header|Wren}}: Minor tidy)
(38 intermediate revisions by 16 users not shown)
Line 49:
end do
</pre>
Note that this an [[wp:Anamorphism |anamorphism]] – dual to catamorphism, and encoded in some languages as a general higher-order `unfold` function, dual to `fold` or `reduce`.
 
;Task:
Line 71:
* Show your output here, on this page.
 
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">T PCG32
UInt64 state, inc
 
F next_int()
V old = .state
.state = (old * 6364136223846793005) + .inc
V shifted = UInt32(((old >> 18) (+) old) >> 27)
V rot = UInt32(old >> 59)
R (shifted >> rot) [|] (shifted << ((~rot + 1) [&] 31))
 
F seed(UInt64 seed_state, seed_sequence)
.state = 0
.inc = (seed_sequence << 1) [|] 1
.next_int()
.state += seed_state
.next_int()
 
F next_float()
R Float(.next_int()) / (UInt64(1) << 32)
 
V random_gen = PCG32()
random_gen.seed(42, 54)
L 5
print(random_gen.next_int())
 
random_gen.seed(987654321, 1)
V hist = Dict(0.<5, i -> (i, 0))
L 100'000
hist[Int(random_gen.next_float() * 5)]++
print(hist)</syntaxhighlight>
 
{{out}}
<pre>
2707161783
2068313097
3122475824
2211639955
3215226955
[0 = 20049, 1 = 20022, 2 = 20115, 3 = 19809, 4 = 20005]
</pre>
 
=={{header|Ada}}==
Ada solution using a package to encapsulate the PCG32 algorithm.
<syntaxhighlight lang="ada">with Interfaces; use Interfaces;
 
package random_pcg32 is
function Next_Int return Unsigned_32;
function Next_Float return Long_Float;
procedure Seed (seed_state : Unsigned_64; seed_sequence : Unsigned_64);
end random_pcg32;
</syntaxhighlight>
 
<syntaxhighlight lang="ada">package body random_pcg32 is
 
State : Unsigned_64 := 0;
inc : Unsigned_64 := 0;
 
----------------
-- Next_State --
----------------
 
procedure Next_State is
N : constant Unsigned_64 := 6_364_136_223_846_793_005;
begin
State := State * N + inc;
end Next_State;
 
--------------
-- Next_Int --
--------------
 
function Next_Int return Unsigned_32 is
old : Unsigned_64 := State;
shifted : Unsigned_32;
Rot : Unsigned_64;
answer : Unsigned_32;
Mask32 : constant Unsigned_64 := Unsigned_64 (Unsigned_32'Last);
begin
shifted := Unsigned_32((((old / 2**18) xor old) / 2**27) and Mask32);
Rot := old / 2**59;
answer :=
Shift_Right (shifted, Integer (Rot)) or
Shift_Left (shifted, Integer ((not Rot + 1) and 31));
Next_State;
return answer;
end Next_Int;
 
----------------
-- Next_Float --
----------------
 
function Next_Float return Long_Float is
begin
return Long_Float (Next_Int) / (2.0**32);
end Next_Float;
 
----------
-- Seed --
----------
 
procedure Seed (seed_state : Unsigned_64; seed_sequence : Unsigned_64) is
begin
State := 0;
inc := (2 * seed_sequence) or 1;
Next_State;
State := State + seed_state;
Next_State;
end Seed;
 
end random_pcg32;
</syntaxhighlight>
 
<syntaxhighlight lang="ada">with Ada.Text_Io; use ADa.Text_io;
with Interfaces; use Interfaces;
with random_pcg32; use random_pcg32;
 
procedure Main_P is
counts : array (0..4) of Natural := (Others => 0);
J : Natural;
begin
seed(42, 54);
for I in 1..5 loop
Put_Line(Unsigned_32'Image(Next_Int));
end loop;
New_Line;
seed(987654321, 1);
for I in 1..100_000 loop
J := Natural(Long_Float'Floor(Next_Float * 5.0));
Counts(J) := Counts(J) + 1;
end loop;
for I in Counts'Range loop
Put_Line(I'Image & " :" & Counts(I)'Image);
end loop;
end Main_P;
</syntaxhighlight>
{{output}}
<pre>
2707161783
2068313097
3122475824
2211639955
3215226955
 
0 : 20049
1 : 20022
2 : 20115
3 : 19809
4 : 20005
</pre>
 
=={{header|ALGOL 68}}==
{{works with|ALGOL 68G|Any - tested with release 2.8.3.win32}}
<langsyntaxhighlight lang="algol68">BEGIN # generate some pseudo random numbers using PCG32 #
# note that although LONG INT is 64 bits in Algol 68G, LONG BITS is longer than 64 bits #
LONG BITS state := LONG 16r853c49e6748fea9b;
Line 130 ⟶ 286:
print( ( newline ) )
END
END</langsyntaxhighlight>
{{out}}
<pre>
Line 143 ⟶ 299:
=={{header|C}}==
{{trans|Go}}
<langsyntaxhighlight lang="c">#include <math.h>
#include <stdint.h>
#include <stdio.h>
Line 196 ⟶ 352:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>2707161783
Line 210 ⟶ 366:
3 : 19809
4 : 20005</pre>
 
=={{header|C#}}==
{{trans|C++}}
<syntaxhighlight lang="C#">
using System;
 
class PCG32
{
private const ulong N = 6364136223846793005;
private ulong state = 0x853c49e6748fea9b;
private ulong inc = 0xda3e39cb94b95bdb;
 
public uint NextInt()
{
ulong old = state;
state = old * N + inc;
uint shifted = (uint)(((old >> 18) ^ old) >> 27);
uint rot = (uint)(old >> 59);
return (shifted >> (int)rot) | (shifted << (int)((~rot + 1) & 31));
}
 
public double NextFloat()
{
return ((double)NextInt()) / (1UL << 32);
}
 
public void Seed(ulong seedState, ulong seedSequence)
{
state = 0;
inc = (seedSequence << 1) | 1;
NextInt();
state += seedState;
NextInt();
}
}
 
class Program
{
static void Main(string[] args)
{
var r = new PCG32();
 
r.Seed(42, 54);
Console.WriteLine(r.NextInt());
Console.WriteLine(r.NextInt());
Console.WriteLine(r.NextInt());
Console.WriteLine(r.NextInt());
Console.WriteLine(r.NextInt());
Console.WriteLine();
 
int[] counts = new int[5];
r.Seed(987654321, 1);
for (int i = 0; i < 100000; i++)
{
int j = (int)Math.Floor(r.NextFloat() * 5.0);
counts[j]++;
}
 
Console.WriteLine("The counts for 100,000 repetitions are:");
for (int i = 0; i < counts.Length; i++)
{
Console.WriteLine($" {i} : {counts[i]}");
}
}
}
</syntaxhighlight>
{{out}}
<pre>
2707161783
2068313097
3122475824
2211639955
3215226955
 
The counts for 100,000 repetitions are:
0 : 20049
1 : 20022
2 : 20115
3 : 19809
4 : 20005
 
</pre>
 
 
=={{header|C++}}==
{{trans|C}}
<langsyntaxhighlight lang="cpp">#include <array>
#include <iostream>
#include <math.h>
 
class PCG32 {
Line 267 ⟶ 507:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>2707161783
Line 284 ⟶ 524:
=={{header|D}}==
{{trans|C++}}
<langsyntaxhighlight lang="d">import std.math;
import std.stdio;
 
Line 337 ⟶ 577:
writeln(" ", i, " : ", v);
}
}</langsyntaxhighlight>
{{out}}
<pre>2707161783
Line 351 ⟶ 591:
3 : 19809
4 : 20005</pre>
 
=={{header|Dart}}==
{{trans|Python}}
<syntaxhighlight lang="Dart">
import 'dart:math';
 
class PCG32 {
BigInt fState = BigInt.zero;
BigInt fInc = BigInt.zero;
final BigInt mask64 = (BigInt.one << 64) - BigInt.one;
final BigInt mask32 = (BigInt.one << 32) - BigInt.one;
final BigInt k = BigInt.parse('6364136223846793005');
 
PCG32(BigInt seedState, BigInt seedSequence) {
seed(seedState, seedSequence);
}
 
PCG32.noSeed() {
fState = BigInt.zero;
fInc = BigInt.zero;
}
 
void seed(BigInt seedState, BigInt seedSequence) {
fState = BigInt.zero;
fInc = ((seedSequence << 1) | BigInt.one) & mask64;
nextInt();
fState += seedState;
nextInt();
}
 
BigInt nextInt() {
BigInt old = fState;
fState = ((old * k) + fInc) & mask64;
BigInt xorshifted = ( ((old >> 18) ^ old) >> 27) & mask32;
BigInt rot = (old >> 59) & mask32;
BigInt shifted = (xorshifted >> rot.toInt()) | (xorshifted << ((-rot) & BigInt.from(31)).toInt());
return shifted & mask32;
}
 
double nextFloat() {
return nextInt().toDouble() / (BigInt.one << 32).toDouble();
}
 
List<BigInt> nextIntRange(int size) {
List<BigInt> result = [];
for (int i = 0; i < size; i++) {
result.add(nextInt());
}
return result;
}
}
 
void main() {
var pcg32 = PCG32(BigInt.from(42), BigInt.from(54));
 
for (int i = 0; i < 5; i++) {
print(pcg32.nextInt().toString());
}
 
pcg32.seed(BigInt.from(987654321), BigInt.one);
 
var count = <int, int>{};
 
for (int i = 0; i < 100000; i++) {
int key = (pcg32.nextFloat() * 5).truncate();
count[key] = (count[key] ?? 0) + 1;
}
 
print('\nThe counts for 100,000 repetitions are:');
count.forEach((key, value) {
print('$key : $value');
});
}
</syntaxhighlight>
{{out}}
<pre>
2707161783
2068313097
3122475824
2211639955
3215226955
 
The counts for 100,000 repetitions are:
2 : 20115
3 : 19809
0 : 20049
4 : 20005
1 : 20022
 
</pre>
 
=={{header|Delphi}}==
Line 358 ⟶ 688:
{{libheader| System.Generics.Collections}}
{{Trans|Python}}
<syntaxhighlight lang="delphi">
<lang Delphi>
program PCG32_test;
 
Line 479 ⟶ 809:
Readln;
end.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 498 ⟶ 828:
=={{header|F_Sharp|F#}}==
===The Functions===
<langsyntaxhighlight lang="fsharp">
// PCG32. Nigel Galloway: August 13th., 2020
let N=6364136223846793005UL
Line 504 ⟶ 834:
let pcg32=Seq.unfold(fun(n,g)->let rot,xs=uint32(g>>>59),uint32(((g>>>18)^^^g)>>>27) in Some(uint32((xs>>>(int rot))|||(xs<<<(-(int rot)&&&31))),(n,g*N+n)))
let pcgFloat n=pcg32 n|>Seq.map(fun n-> (float n)/4294967296.0)
</syntaxhighlight>
</lang>
===The Tasks===
<langsyntaxhighlight lang="fsharp">
pcg32(seed 42UL 54UL)|>Seq.take 5|>Seq.iter(printfn "%d")
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 517 ⟶ 847:
3215226955
</pre>
<langsyntaxhighlight lang="fsharp">
pcgFloat(seed 987654321UL 1UL)|>Seq.take 100000|>Seq.countBy(fun n->int(n*5.0))|>Seq.iter(printf "%A");printfn ""
</syntaxhighlight>
</lang>
<pre>
(2, 20115)(3, 19809)(0, 20049)(4, 20005)(1, 20022)
</pre>
 
=={{header|Factor}}==
{{trans|Python}}
{{works with|Factor|0.99 2020-08-14}}
<langsyntaxhighlight lang="factor">USING: accessors kernel locals math math.bitwise math.statistics
prettyprint sequences ;
 
Line 558 ⟶ 889:
987654321 1 [ seed ] keepdd
100,000 [ dup next-float 5 * >integer ] replicate nip
histogram .</langsyntaxhighlight>
{{out}}
<pre>
Line 571 ⟶ 902:
=={{header|Go}}==
{{trans|Python}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 621 ⟶ 952:
fmt.Printf(" %d : %d\n", i, counts[i])
}
}</langsyntaxhighlight>
 
{{out}}
Line 638 ⟶ 969:
4 : 20005
</pre>
 
=={{header|Haskell}}==
 
Implement given algorithm as an instance of <code>RandomGen</code> class.
 
<syntaxhighlight lang="haskell">import Data.Bits
import Data.Word
import System.Random
import Data.List
 
data PCGen = PCGen !Word64 !Word64
 
mkPCGen state sequence =
let
n = 6364136223846793005 :: Word64
inc = (sequence `shiftL` 1) .|. 1 :: Word64
in PCGen ((inc + state)*n + inc) inc
 
instance RandomGen PCGen where
next (PCGen state inc) =
let
n = 6364136223846793005 :: Word64
xs = fromIntegral $ ((state `shiftR` 18) `xor` state) `shiftR` 27 :: Word32
rot = fromIntegral $ state `shiftR` 59 :: Int
in (fromIntegral $ (xs `shiftR` rot) .|. (xs `shiftL` ((-rot) .&. 31))
, PCGen (state * n + inc) inc)
 
split _ = error "PCG32 is not splittable"
 
randoms' :: RandomGen g => g -> [Int]
randoms' g = unfoldr (pure . next) g
 
toFloat n = fromIntegral n / (2^32 - 1)</syntaxhighlight>
 
Direct usage of generator:
<pre>*Main> take 5 $ randoms' (mkPCGen 42 54)
[2707161783,2068313097,3122475824,2211639955,3215226955]
 
*Main> let hist = map length . group . sort
*Main> hist . take 100000 $ (floor . (*5) . toFloat) <$> (randoms' (mkPCGen 987654321 1))
[20049,20022,20115,19809,20005]</pre>
 
Using <code>Random</code> class gives different results due to internal shuffling:
<pre>*Main> take 5 $ randoms (mkPCGen 42 54)
[2068313097,2211639955,3421331566,2167406445,4181216144]
 
*Main>let hist = map length . group . sort
*Main> hist . take 100000 $ (floor . (*5)) <$> (randoms (mkPCGen 987654321 1) :: [Float])
[20009,20065,20023,19876,20027]</pre>
 
=={{header|J}}==
 
Implementation:
<syntaxhighlight lang="j">PCG32GEN=: {{
g=. cocreate''
'state0__g seq__g'=. m
init__g=: {{
max=: 2^64x
u64=: &.((64#2x)&#:) NB. binary domain operation
U64=: max&| NB. integer domain result
U32=: (2^32)&(<.@|)
and=: *. u64
xor=: ~: u64
or=: +. u64
lsl=: max <.@| ] * 2x^[
N=: 6364136223846793005x
inc=: U64 1 2x p. seq
state=: U64 inc+N*inc+state0
}}
next__g=: g {{ m[y
xs=. U32 _27 lsl state xor _18 lsl state
rot=. -_59 lsl state
state=: U64 inc+N*state
U32 (rot lsl xs) or (31 and rot) lsl xs
}}
init__g''
(;'next_';(;g);'_')~
}}
 
next_float=: %&(2^32)</syntaxhighlight>
 
Task examples:
 
<syntaxhighlight lang="j"> 42 54 PCG32GEN ^:(1+i.5)''
2707161776 2068313120 3122475824 2211639955 3215226955
(~.,. #/.~) <.5*next_float 987654321 1 PCG32GEN^:(1+i.1e5) ''
2 20115
3 19809
0 20049
4 20005
1 20022</syntaxhighlight>
 
=={{header|Java}}==
{{trans|C++}}
<syntaxhighlight lang="java">public class PCG32 {
private static final long N = 6364136223846793005L;
 
private long state = 0x853c49e6748fea9bL;
private long inc = 0xda3e39cb94b95bdbL;
 
public void seed(long seedState, long seedSequence) {
state = 0;
inc = (seedSequence << 1) | 1;
nextInt();
state = state + seedState;
nextInt();
}
 
public int nextInt() {
long old = state;
state = old * N + inc;
int shifted = (int) (((old >>> 18) ^ old) >>> 27);
int rot = (int) (old >>> 59);
return (shifted >>> rot) | (shifted << ((~rot + 1) & 31));
}
 
public double nextFloat() {
var u = Integer.toUnsignedLong(nextInt());
return (double) u / (1L << 32);
}
 
public static void main(String[] args) {
var r = new PCG32();
 
r.seed(42, 54);
System.out.println(Integer.toUnsignedString(r.nextInt()));
System.out.println(Integer.toUnsignedString(r.nextInt()));
System.out.println(Integer.toUnsignedString(r.nextInt()));
System.out.println(Integer.toUnsignedString(r.nextInt()));
System.out.println(Integer.toUnsignedString(r.nextInt()));
System.out.println();
 
int[] counts = {0, 0, 0, 0, 0};
r.seed(987654321, 1);
for (int i = 0; i < 100_000; i++) {
int j = (int) Math.floor(r.nextFloat() * 5.0);
counts[j]++;
}
 
System.out.println("The counts for 100,000 repetitions are:");
for (int i = 0; i < counts.length; i++) {
System.out.printf(" %d : %d\n", i, counts[i]);
}
}
}</syntaxhighlight>
{{out}}
<pre>2707161783
2068313097
3122475824
2211639955
3215226955
 
The counts for 100,000 repetitions are:
0 : 20049
1 : 20022
2 : 20115
3 : 19809
4 : 20005</pre>
 
=={{header|Julia}}==
{{trans|Python}}
<langsyntaxhighlight lang="julia">const mask32, CONST = 0xffffffff, UInt(6364136223846793005)
 
mutable struct PCG32
Line 687 ⟶ 1,176:
 
testPCG32()
</langsyntaxhighlight>{{out}}
<pre>
2707161783
Line 701 ⟶ 1,190:
{{trans|C++}}
Requires the experimental unsigned feature for integer types
<langsyntaxhighlight lang="scala">import kotlin.math.floor
 
class PCG32 {
Line 754 ⟶ 1,243:
println(" %d : %d".format(iv.index, iv.value))
}
}</langsyntaxhighlight>
{{out}}
<pre>2707161783
Line 768 ⟶ 1,257:
3 : 19809
4 : 20005</pre>
 
=={{header|Lua}}==
{{trans|C}}
<syntaxhighlight lang="lua">function uint32(n)
return n & 0xffffffff
end
function uint64(n)
return n & 0xffffffffffffffff
end
N = 6364136223846793005
state = 0x853c49e6748fea9b
inc = 0xda3e39cb94b95bdb
function pcg32_seed(seed_state, seed_sequence)
state = 0
inc = (seed_sequence << 1) | 1
pcg32_int()
state = state + seed_state
pcg32_int()
end
function pcg32_int()
local old = state
state = uint64(old * N + inc)
local shifted = uint32(((old >> 18) ~ old) >> 27)
local rot = uint32(old >> 59)
return uint32((shifted >> rot) | (shifted << ((~rot + 1) & 31)))
end
function pcg32_float()
return 1.0 * pcg32_int() / (1 << 32)
end
-------------------------------------------------------------------
pcg32_seed(42, 54)
print(pcg32_int())
print(pcg32_int())
print(pcg32_int())
print(pcg32_int())
print(pcg32_int())
print()
counts = { 0, 0, 0, 0, 0 }
pcg32_seed(987654321, 1)
for i=1,100000 do
local j = math.floor(pcg32_float() * 5.0) + 1
counts[j] = counts[j] + 1
end
print("The counts for 100,000 repetitions are:")
for i=1,5 do
print(" " .. (i - 1) .. ": " .. counts[i])
end</syntaxhighlight>
{{out}}
<pre>2707161783
2068313097
3122475824
2211639955
3215226955
 
The counts for 100,000 repetitions are:
0: 20049
1: 20022
2: 20115
3: 19809
4: 20005</pre>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
{{trans|Julia}}
<syntaxhighlight lang="Mathematica">
ClearAll["Global`*"];
 
(*Constants*)
mask32 = BitAnd[2^32 - 1];
CONST = 6364136223846793005;
 
(*Convert Hex String to Expression*)
Hex[x_?StringQ] := ToExpression["16^^" <> StringDrop[x, 2]];
 
(*Definition of PCG32 Structure*)
PCG32[state_: Hex["0x853c49e6748fea9b"],
inc_: Hex["0xda3e39cb94b95bdb"]] := <|"state" -> state,
"inc" -> inc|>;
 
(*Function to generate next integer*)
nextInt[pcg_Association] :=
Module[{old, xorshifted, rot, newState}, old = pcg["state"];
newState = BitAnd[(old*CONST + pcg["inc"]), 2^64 - 1];
xorshifted =
BitAnd[BitShiftRight[BitXor[BitShiftRight[old, 18], old], 27],
mask32];
rot = BitAnd[BitShiftRight[old, 59], mask32];
<|"state" -> newState, "inc" -> pcg["inc"],
"nextInt" ->
BitAnd[BitOr[BitShiftRight[xorshifted, rot],
BitShiftLeft[xorshifted, BitAnd[-rot, 31]]], mask32]|>];
 
(*Function to generate next float*)
nextFloat[pcg_Association] := nextInt[pcg]["nextInt"]/2^32;
 
(*Function to seed the generator*)
seed[pcg_Association, st_, seq_] :=
Module[{newPcg},
newPcg = <|"state" -> 0,
"inc" -> BitOr[BitShiftLeft[seq, 1], 1]|>;
newPcg = nextInt[newPcg];
<|"state" -> newPcg["state"] + st, "inc" -> newPcg["inc"]|>];
 
(*Test function*)
testPCG32[] :=
Module[{randomGen, hist, n, nextGen}, randomGen = PCG32[];
randomGen = seed[randomGen, 42, 54];
Do[
nextGen = nextInt[randomGen];
randNumber = nextGen["nextInt"];
If[randNumber != 0, Print[randNumber]];
randomGen = nextGen
, {6}];
randomGen = seed[randomGen, 987654321, 1];
hist = ConstantArray[0, 5];
Do[nextGen = nextInt[randomGen];
hist[[Floor[nextFloat[nextGen]*5] + 1]] += 1;
randomGen = nextGen, {100000}];
Print[hist];
Do[Print[n - 1, ": ", hist[[n]], " "], {n, 1, 5}];];
 
(*Run the test*)
testPCG32[];
</syntaxhighlight>
{{out}}
<pre>
2707161783
2068313097
3122475824
2211639955
3215226955
{20049, 20022, 20115, 19809, 20005}
0: 20049
1: 20022
2: 20115
3: 19809
4: 20005
 
</pre>
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">import algorithm, sequtils, strutils, tables
 
const N = 6364136223846793005u64
 
type PCG32 = object
inc: uint64
state: uint64
 
func seed(gen: var PCG32; seedState, seedSequence: uint64) =
gen.inc = seedSequence shl 1 or 1
gen.state = (gen.inc + seedState) * N + gen.inc
 
func nextInt(gen: var PCG32): uint32 =
let xs = uint32((gen.state shr 18 xor gen.state) shr 27)
let rot = int32(gen.state shr 59)
result = uint32(xs shr rot or xs shl (-rot and 31))
gen.state = gen.state * N + gen.inc
 
func nextFloat(gen: var PCG32): float =
gen.nextInt().float / float(0xFFFFFFFFu32)
 
 
when isMainModule:
 
var gen: PCG32
 
gen.seed(42, 54)
for _ in 1..5:
echo gen.nextInt()
 
echo ""
gen.seed(987654321, 1)
var counts: CountTable[int]
for _ in 1..100_000:
counts.inc int(gen.nextFloat() * 5)
echo sorted(toSeq(counts.pairs)).mapIt($it[0] & ": " & $it[1]).join(", ")</syntaxhighlight>
 
{{out}}
<pre>2707161783
2068313097
3122475824
2211639955
3215226955
 
0: 20049, 1: 20022, 2: 20115, 3: 19809, 4: 20005</pre>
 
=={{header|OCaml}}==
<syntaxhighlight lang="ocaml">let (>>) = Int64.shift_right_logical
 
let int32_bound n x =
Int64.(to_int ((mul (logand (of_int32 x) 0xffffffffL) (of_int n)) >> 32))
 
let int32_rotate_right x n =
Int32.(logor (shift_left x (-n land 31)) (shift_right_logical x n))
 
let pcg32_next inc st =
Int64.(add (mul st 0x5851f42d4c957f2dL) inc)
 
let pcg32_output st =
int32_rotate_right
(Int32.logxor (Int64.to_int32 (st >> 27)) (Int64.to_int32 (st >> 45)))
(Int64.to_int (st >> 59))
 
let seq_pcg32 (st, f) =
let rec repeat st () = Seq.Cons (pcg32_output st, repeat (f st)) in
repeat (f st)
 
let pcg32 seed_st seed_sq =
let inc = Int64.(add (succ seed_sq) seed_sq) in
Int64.add seed_st inc, pcg32_next inc</syntaxhighlight>
;<nowiki>Test:</nowiki>
<syntaxhighlight lang="ocaml">let () =
pcg32 42L 54L |> seq_pcg32 |> Seq.take 5
|> Seq.iter (Printf.printf " %lu") |> print_newline
 
let () =
pcg32 987654321L 1L |> seq_pcg32 |> Seq.map (int32_bound 5) |> Seq.take 100000
|> Seq.fold_left (fun a n -> a.(n) <- succ a.(n); a) (Array.make 5 0)
|> Array.iteri (Printf.printf "%u: %u\n")</syntaxhighlight>
{{out}}
<pre>
2707161783 2068313097 3122475824 2211639955 3215226955
0: 20049
1: 20022
2: 20115
3: 19809
4: 20005
</pre>
 
=={{header|Perl}}==
<langsyntaxhighlight lang="perl">use strict;
use warnings;
use feature 'say';
use Math::AnyNum qw(:overload);
 
{ package PCG32; {
 
use constant {
our($state,$incr);
use constant mask32 => 2**32 - 1;,
use constant mask64 => 2**64 - 1;,
use constant const => 6364136223846793005;,
};
 
sub new {
my ($seedclass, $iincr%opt) = ($@_[2], $_[4]);
my $seed = $opt{seed} //= 1;
my $iincrincr = $opt{incr} //= 2;
$incr = $iincrincr << 1 | 1 & mask64;
my $state = (($incr + $seed) * const + $incr) & mask64;
bless {incr => $incr, state => $state}, $class;
}
 
sub next_int {
my ($self) = @_;
my $state = $self->{state};
my $shift = ($state >> 18 ^ $state) >> 27 & mask32;
my $rotate = $state >> 59 & mask32;
$self->{state } = ($state * const + $self->{incr}) & mask64;
($shift >> $rotate) | $shift << (32 - $rotate) & mask32;
}
 
sub next_float {
my ($self) = @_;
$self->next_int / 2**32;
}
}
Line 800 ⟶ 1,535:
say "Seed: 42, Increment: 54, first 5 values:";
my $rng = PCG32->new(seed => 42, incr => 54);
say PCG32$rng->next_int($rng) for 1 .. 5;
 
say "\nSeed: 987654321, Increment: 1, values histogram:";
my %h;
$rng = PCG32->new( seed => 987654321, incr => 1 );
$h{int 5 * PCG32->next_int($rng)/2**32->next_float}++ for 1 .. 100_000;
say "$_ $h{$_}" for sort keys %h;</langsyntaxhighlight>
{{out}}
<pre>Seed: 42, Increment: 54, first 5 values:
Line 827 ⟶ 1,562:
Phix atoms are limited to 53/64 bits of precision, however (given the above) this task would need 128 bits.<br>
First, for comparison only, this is the usual recommended native approach for this genre of task (different output)
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>puts(1,"NB: These are not expected to match the task spec!\n")
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"NB: These are not expected to match the task spec!\n"</span><span style="color: #0000FF;">)</span>
set_rand(42)
<span style="color: #7060A8;">set_rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">42</span><span style="color: #0000FF;">)</span>
for i=1 to 5 do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">5</span> <span style="color: #008080;">do</span>
printf(1,"%d\n",rand(-1))
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d\n"</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">rand</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">))</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
set_rand(987654321)
<span style="color: #7060A8;">set_rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">987654321</span><span style="color: #0000FF;">)</span>
sequence s = repeat(0,5)
<span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)</span>
for i=1 to 100000 do
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">100000</span> <span style="color: #008080;">do</span>
s[floor(rnd()*5)+1] += 1
<span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">rnd</span><span style="color: #0000FF;">()*</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
end for
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
?s</lang>
<span style="color: #0000FF;">?</span><span style="color: #000000;">s</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 848 ⟶ 1,585:
{20080,19802,19910,20039,20169}
</pre>
To meet the spec, similar to the Delphi and Wren entries, we resort to using mpfr/gmp, but it is a fair bit longer than the above, and almost certainly slower, thannot thethat abovethere is anywhere near enough work being done here to make that measureable.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>include mpfr.e
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
mpz const = mpz_init("6364136223846793005"),
<span style="color: #008080;">include</span> <span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
state = mpz_init("0x853c49e6748fea9b"),
<span style="color: #004080;">mpz</span> <span style="color: #000000;">cmult</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"6364136223846793005"</span><span style="color: #0000FF;">),</span>
inc = mpz_init("0xda3e39cb94b95bdb"), /* Always odd */
<span style="color: #000000;">state</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"0x853c49e6748fea9b"</span><span style="color: #0000FF;">),</span>
b64 = mpz_init("0x10000000000000000"), -- (truncate to 64 bits)
<span style="color: #000000;">inc</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"0xda3e39cb94b95bdb"</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">/* Always odd */</span>
b32 = mpz_init("0x100000000"), -- (truncate to 32 bits)
<span style="color: #000000;">b64</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"0x10000000000000000"</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- (truncate to 64 bits)</span>
old = mpz_init(),
<span style="color: #000000;">b32</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"0x100000000"</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- (truncate to 32 bits)</span>
xorsh = mpz_init()
<span style="color: #000000;">old</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">(),</span>
<span style="color: #000000;">xorsh</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_init</span><span style="color: #0000FF;">()</span>
procedure seed(integer seed_state, seed_sequence)
mpz_set_si(inc,seed_sequence*2+1)
<span style="color: #008080;">procedure</span> <span style="color: #000000;">seed</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">seed_state</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">seed_sequence</span><span style="color: #0000FF;">)</span>
-- as per the talk page:
<span style="color: #7060A8;">mpz_set_si</span><span style="color: #0000FF;">(</span><span style="color: #000000;">inc</span><span style="color: #0000FF;">,</span><span style="color: #000000;">seed_sequence</span><span style="color: #0000FF;">*</span><span style="color: #000000;">2</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
-- state := remainder((inc+seed_state)*const+inc,b64)
<span style="color: #000080;font-style:italic;">-- as per the talk page:
mpz_add_ui(state,inc,seed_state)
-- state := remainder((inc+seed_state)*cmult+inc,b64)</span>
mpz_mul(state,state,const)
<span style="color: #7060A8;">mpz_add_ui</span><span style="color: #0000FF;">(</span><span style="color: #000000;">state</span><span style="color: #0000FF;">,</span><span style="color: #000000;">inc</span><span style="color: #0000FF;">,</span><span style="color: #000000;">seed_state</span><span style="color: #0000FF;">)</span>
mpz_add(state,state,inc)
<span style="color: #7060A8;">mpz_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">state</span><span style="color: #0000FF;">,</span><span style="color: #000000;">state</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cmult</span><span style="color: #0000FF;">)</span>
mpz_fdiv_r(state, state, b64) -- state := remainder(state,b64)
<span style="color: #7060A8;">mpz_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">state</span><span style="color: #0000FF;">,</span><span style="color: #000000;">state</span><span style="color: #0000FF;">,</span><span style="color: #000000;">inc</span><span style="color: #0000FF;">)</span>
end procedure
<span style="color: #7060A8;">mpz_fdiv_r</span><span style="color: #0000FF;">(</span><span style="color: #000000;">state</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b64</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- state := remainder(state,b64) </span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
function next_int()
mpz_set(old,state) -- old := state
<span style="color: #008080;">function</span> <span style="color: #000000;">next_int</span><span style="color: #0000FF;">()</span>
mpz_set(state,inc) -- state := inc
<span style="color: #7060A8;">mpz_set</span><span style="color: #0000FF;">(</span><span style="color: #000000;">old</span><span style="color: #0000FF;">,</span><span style="color: #000000;">state</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- old := state</span>
mpz_addmul(state,old,const) -- state += old*const
<span style="color: #7060A8;">mpz_set</span><span style="color: #0000FF;">(</span><span style="color: #000000;">state</span><span style="color: #0000FF;">,</span><span style="color: #000000;">inc</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- state := inc</span>
mpz_fdiv_r(state, state, b64) -- state := remainder(state,b64)
<span style="color: #7060A8;">mpz_addmul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">state</span><span style="color: #0000FF;">,</span><span style="color: #000000;">old</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cmult</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- state += old*cmult</span>
mpz_tdiv_q_2exp(xorsh, old, 18) -- xorsh := trunc(old/2^18)
<span style="color: #7060A8;">mpz_fdiv_r</span><span style="color: #0000FF;">(</span><span style="color: #000000;">state</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">state</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b64</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- state := remainder(state,b64) </span>
mpz_xor(xorsh, xorsh, old) -- xorsh := xor_bits(xorsh,old)
<span style="color: #7060A8;">mpz_tdiv_q_2exp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xorsh</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">old</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">18</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- xorsh := trunc(old/2^18)</span>
mpz_tdiv_q_2exp(xorsh, xorsh, 27) -- xorsh := trunc(xorsh/2^17)
<span style="color: #7060A8;">mpz_xor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xorsh</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">xorsh</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">old</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- xorsh := xor_bits(xorsh,old)</span>
mpz_fdiv_r(xorsh, xorsh, b32) -- xorsh := remainder(xorsh,b32)
<span style="color: #7060A8;">mpz_tdiv_q_2exp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xorsh</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">xorsh</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">27</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- xorsh := trunc(xorsh/2^27)</span>
atom xorshifted = mpz_get_atom(xorsh)
<span style="color: #7060A8;">mpz_fdiv_r</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xorsh</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">xorsh</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b32</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- xorsh := remainder(xorsh,b32) </span>
mpz_tdiv_q_2exp(old, old, 59) -- old := trunc(old/2^59)
<span style="color: #004080;">atom</span> <span style="color: #000000;">xorshifted</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_get_atom</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xorsh</span><span style="color: #0000FF;">)</span>
integer rot = mpz_get_integer(old)
<span style="color: #7060A8;">mpz_tdiv_q_2exp</span><span style="color: #0000FF;">(</span><span style="color: #000000;">old</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">old</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">59</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- old := trunc(old/2^59)</span>
atom answer = xor_bitsu((xorshifted >> rot),(xorshifted << 32-rot))
<span style="color: #004080;">integer</span> <span style="color: #000000;">rot</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">mpz_get_integer</span><span style="color: #0000FF;">(</span><span style="color: #000000;">old</span><span style="color: #0000FF;">)</span>
return answer
<span style="color: #004080;">atom</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">and_bitsu</span><span style="color: #0000FF;">(</span><span style="color: #000000;">xorshifted</span> <span style="color: #0000FF;"><<</span> <span style="color: #000000;">32</span><span style="color: #0000FF;">-</span><span style="color: #000000;">rot</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">#FFFFFFFF</span><span style="color: #0000FF;">),</span>
end function
<span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">xorshifted</span> <span style="color: #0000FF;">>></span> <span style="color: #000000;">rot</span><span style="color: #0000FF;">,</span>
 
<span style="color: #000000;">answer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">xor_bitsu</span><span style="color: #0000FF;">(</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,</span><span style="color: #000000;">r</span><span style="color: #0000FF;">)</span>
function next_float()
<span style="color: #008080;">return</span> <span style="color: #000000;">answer</span>
return next_int() / (1 << 32)
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
end function
<span style="color: #008080;">function</span> <span style="color: #000000;">next_float</span><span style="color: #0000FF;">()</span>
seed(42, 54)
<span style="color: #008080;">return</span> <span style="color: #000000;">next_int</span><span style="color: #0000FF;">()</span> <span style="color: #0000FF;">/</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">1</span> <span style="color: #0000FF;"><<</span> <span style="color: #000000;">32</span><span style="color: #0000FF;">)</span>
for i=1 to 5 do
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
printf(1,"%d\n",next_int())
end for
<span style="color: #000000;">seed</span><span style="color: #0000FF;">(</span><span style="color: #000000;">42</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">54</span><span style="color: #0000FF;">)</span>
seed(987654321,1)
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">5</span> <span style="color: #008080;">do</span>
sequence r = repeat(0,5)
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">next_int</span><span style="color: #0000FF;">())</span>
for i=1 to 100000 do
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
r[floor(next_float()*5)+1] += 1
<span style="color: #000000;">seed</span><span style="color: #0000FF;">(</span><span style="color: #000000;">987654321</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
end for
<span style="color: #004080;">sequence</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)</span>
?r</lang>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">100000</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">idx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">next_float</span><span style="color: #0000FF;">()*</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span>
<span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">r</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 909 ⟶ 1,652:
 
=={{header|Python}}==
 
<lang python>mask64 = (1 << 64) - 1
===Python: As class===
<syntaxhighlight lang="python">mask64 = (1 << 64) - 1
mask32 = (1 << 32) - 1
CONST = 6364136223846793005
Line 955 ⟶ 1,700:
for i in range(100_000):
hist[int(random_gen.next_float() *5)] += 1
print(hist)</langsyntaxhighlight>
 
{{out}}
<pre>2707161783
2068313097
3122475824
2211639955
3215226955
{0: 20049, 1: 20022, 2: 20115, 3: 19809, 4: 20005}</pre>
 
===Python: As generator===
 
<syntaxhighlight lang="python">def pcg32(seed_state=None, seed_sequence=None, as_int=True):
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 as_int else next_int() / (1 << 32)
 
 
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, as_int=False), 100_000):
hist[int(i * 5)] += 1
print(hist)</syntaxhighlight>
 
{{out}}
Line 971 ⟶ 1,760:
Raku does not have unsigned Integers at this time (Integers are arbitrary sized) so use explicit bit masks during bitwise operations.
 
<syntaxhighlight lang="raku" perl6line>class PCG32 {
has $!state;
has $!incr;
Line 1,012 ⟶ 1,801:
say "\nSeed: default, Increment: default; first five Int values:";
$rng = PCG32.new;
.say for $rng.next-int xx 5;</langsyntaxhighlight>
{{out}}
<pre>Seed: 42, Increment: 54; first five Int values:
Line 1,030 ⟶ 1,819:
3759121132
2984354868</pre>
 
=={{header|REXX}}==
{{trans|Java}}
It was a challenge to understand how some Java constructs work and to end up with the identical output.
DON'T use Rexx, however, for this type of problem unless you take the time spent
for some Java coffees!
<syntaxhighlight lang="rexx">Numeric Digits 40
N = 6364136223846793005
state = x2d('853c49e6748fea9b',16)
inc = x2d('da3e39cb94b95bdb',16)
Call seed 42,54
Do zz=1 To 5
res=nextint()
Say int2str(res)
End
Call seed 987654321,1
cnt.=0
Do i=1 To 100000
z=nextfloat()
cnt.z=cnt.z+1
End
Say ''
Say 'The counts for 100,000 repetitions are:'
Do z=0 To 4
Say format(z,2) ':' format(cnt.z,5)
End
Exit
 
int2str: Procedure
int=arg(1)
intx=d2x(int,8)
res=x2d(copies(0,8)intx,16)
Return res
 
seed:
Parse Arg seedState,seedSequence
state=0
inc=dshift(seedSequence,-1)
inc=x2d(or(d2x(inc,16),d2x(1,16)),16)
z=nextint()
state=javaadd(state,seedState)
z=nextint()
Return
 
nextInt:
old = state
oldxN = javamult(old,n)
statex= javaadd(oldxN,inc)
state=statex
oldx=d2x(old,16)
oldb=x2b(oldx)
oldb18=copies(0,18)left(oldb,64-18)
oldb18o=bxor(oldb18,oldb)
rb=copies(0,27)left(oldb18o,64-27)
rx=b2x(rb)
shifted=x2d(substr(rx,9),8)
oldx=d2x(old,16)
oldb=x2b(oldx)
oldb2=copies(0,59)left(oldb,length(oldb)-59)
oldx2=b2x(oldb2)
rotx=x2d(substr(oldx2,9),8)
t1=ishift(shifted,rotx,'L')
t2=x2d(xneg(d2x(rotx,8)),8)
t3=t2+1
t4=x2d(xand(d2x(t3,8),d2x(31,8)),8)
t5=dshift(shifted,-t4)
t5x=d2x(t5,16)
t5y=substr(t5x,9)
t5z=x2d(t5y,16)
t7=x2d(or(d2x(t1,16),d2x(t5z,16)),16)
t8=long2int(t7)
Return t8
 
nextfloat:
ni=nextint()
nix=d2x(ni,8)
niz=copies(0,8)nix
u=x2d(niz,16)
uu=u/(2**32)
z=uu*5%1
Return z
 
javaadd: Procedure
/**********************************************************************
* Add two long integers and ignore the possible overflow
**********************************************************************/
Numeric Digits 40
Parse Arg a,b
r=a+b
rx=d2x(r,18)
res=right(rx,16)
return x2d(res,16)
 
javamult: Procedure
/**********************************************************************
* Multiply java style
**********************************************************************/
Numeric Digits 40
Parse Arg a,b
m=d2x(a*b,16)
res=x2d(m,16)
Return res
 
bxor: Procedure
/**********************************************************************
* Exclusive Or two bit strings
**********************************************************************/
Parse arg a,b
res=''
Do i=1 To length(a)
res=res||(substr(a,i,1)<>substr(b,i,1))
End
Return res
 
xxor: Procedure
/**********************************************************************
* Exclusive Or two hex strings
**********************************************************************/
Parse Arg u,v
ub=x2b(u)
vb=x2b(v)
res=''
Do i=1 To 64
res=res||(substr(ub,i,1)<>substr(vb,i,1))
End
res=b2x(res)
Return res
 
xand: Procedure
/**********************************************************************
* And two hex strings
**********************************************************************/
Parse Arg u,v
ub=x2b(u)
vb=x2b(v)
res=''
Do i=1 To length(ub)
res=res||(substr(ub,i,1)&substr(vb,i,1))
End
res=b2x(res)
Return res
 
or: Procedure
/**********************************************************************
* Or two hex strings
**********************************************************************/
Parse Arg u,v
ub=x2b(u)
vb=x2b(v)
res=''
Do i=1 To length(ub)
res=res||(substr(ub,i,1)|substr(vb,i,1))
End
res=b2x(res)
Return res
 
long2int: Procedure
/**********************************************************************
* Cast long to int
**********************************************************************/
Parse Arg long
longx=d2x(long,16)
int=x2d(substr(longx,9),8)
Return int
 
xneg: Procedure
/**********************************************************************
* Negate a hex string
**********************************************************************/
Parse Arg s
sb=x2b(s)
res=''
Do i=1 To length(sb)
res=res||\substr(sb,i,1)
End
res=b2x(res)
Return res
 
dshift: Procedure
/**********************************************************************
* Implement the shift operations for a long variable
* r = dshift(long,shift[,mode]) >> Mode='L' logical right shift
* >>> Mode='A' arithmetic right shift
* << xhift<0 left shift
********************************************`*************************/
Parse Upper Arg n,s,o
Numeric Digits 40
If o='' Then o='L'
nx=d2x(n,16)
nb=x2b(nx)
If s<0 Then Do
s=abs(s)
rb=substr(nb,s+1)||copies('0',s)
rx=b2x(rb)
r=x2d(rx,16)
End
Else Do
If o='L' Then Do
rb=left(copies('0',s)nb,length(nb))
rx=b2x(rb)
r=x2d(rx,16)
End
Else Do
rb=left(copies(left(nb,1),s)nb,length(nb))
rx=b2x(rb)
r=x2d(rx,16)
End
End
Return r
 
ishift: Procedure
/**********************************************************************
* Implement the shift operations for an int variable
* r = dshift(int,shift[,mode]) >> Mode='L' logical right shift
* >>> Mode='A' arithmetic right shift
* << xhift<0 left shift
********************************************`*************************/
Parse Upper Arg n,s,o
Numeric Digits 40
If o='' Then o='L'
nx=d2x(n,8)
nb=x2b(nx)
If s<0 Then Do
s=abs(s)
rb=substr(nb,s+1)||copies('0',s)
rx=b2x(rb)
r=x2d(rx,8)
End
Else Do
If o='L' Then Do
rb=left(copies('0',s)nb,length(nb))
rx=b2x(rb)
r=x2d(rx,8)
End
Else Do
rb=left(copies(left(nb,1),s)nb,length(nb))
rx=b2x(rb)
r=x2d(rx,8)
End
End
Return r
 
b2x: Procedure Expose x.
/**********************************************************************
* Convert a Bit string to a Hex stríng
**********************************************************************/
Parse Arg b
z='0'; bits.z='0000'; y=bits.z; x.y=z
z='1'; bits.z='0001'; y=bits.z; x.y=z
z='2'; bits.z='0010'; y=bits.z; x.y=z
z='3'; bits.z='0011'; y=bits.z; x.y=z
z='4'; bits.z='0100'; y=bits.z; x.y=z
z='5'; bits.z='0101'; y=bits.z; x.y=z
z='6'; bits.z='0110'; y=bits.z; x.y=z
z='7'; bits.z='0111'; y=bits.z; x.y=z
z='8'; bits.z='1000'; y=bits.z; x.y=z
z='9'; bits.z='1001'; y=bits.z; x.y=z
z='A'; bits.z='1010'; y=bits.z; x.y=z
z='B'; bits.z='1011'; y=bits.z; x.y=z
z='C'; bits.z='1100'; y=bits.z; x.y=z
z='D'; bits.z='1101'; y=bits.z; x.y=z
z='E'; bits.z='1110'; y=bits.z; x.y=z
z='F'; bits.z='1111'; y=bits.z; x.y=z
x=''
Do While b<>''
Parse Var b b4 +4 b
x=x||x.b4
End
Return x
 
x2b: Procedure Expose bits.
/***********************************************************************
* Convert a Hex string to a Bit stríng
***********************************************************************/
Parse Arg x
z='0'; bits.z='0000'; y=bits.z; x.y=z
z='1'; bits.z='0001'; y=bits.z; x.y=z
z='2'; bits.z='0010'; y=bits.z; x.y=z
z='3'; bits.z='0011'; y=bits.z; x.y=z
z='4'; bits.z='0100'; y=bits.z; x.y=z
z='5'; bits.z='0101'; y=bits.z; x.y=z
z='6'; bits.z='0110'; y=bits.z; x.y=z
z='7'; bits.z='0111'; y=bits.z; x.y=z
z='8'; bits.z='1000'; y=bits.z; x.y=z
z='9'; bits.z='1001'; y=bits.z; x.y=z
z='A'; bits.z='1010'; y=bits.z; x.y=z
z='B'; bits.z='1011'; y=bits.z; x.y=z
z='C'; bits.z='1100'; y=bits.z; x.y=z
z='D'; bits.z='1101'; y=bits.z; x.y=z
z='E'; bits.z='1110'; y=bits.z; x.y=z
z='F'; bits.z='1111'; y=bits.z; x.y=z
b=''
Do While x<>''
Parse Var x c +1 x
b=b||bits.c
End
Return b </syntaxhighlight>
{{out}}
<pre>
2707161783
2068313097
3122475824
2211639955
3215226955
 
The counts for 100,000 repetitions are:
0 : 20049
1 : 20022
2 : 20115
3 : 19809
4 : 20005
</pre>
 
=={{header|Ruby}}==
{{trans|Python}}
<langsyntaxhighlight Rubylang="ruby">class PCG32
MASK64 = (1 << 64) - 1
MASK32 = (1 << 32) - 1
Line 1,066 ⟶ 2,168:
random_gen.seed(987654321, 1)
p 100_000.times.each{(random_gen.next_float * 5).floor}.tally.sort.to_h
</syntaxhighlight>
</lang>
{{out}}
<pre>2707161783
Line 1,075 ⟶ 2,177:
{0=>20049, 1=>20022, 2=>20115, 3=>19809, 4=>20005}
</pre>
 
=={{header|Rust}}==
{{trans|C++}}
<syntaxhighlight lang="Rust">
struct PCG32 {
multiplier: u64,
state: u64,
inc: u64,
}
 
impl PCG32 {
fn new() -> Self {
PCG32 {
multiplier: 6364136223846793005,
state: 0x853c49e6748fea9b,
inc: 0xda3e39cb94b95bdb,
}
}
 
fn next_int(&mut self) -> u32 {
let old = self.state;
self.state = old.wrapping_mul(self.multiplier).wrapping_add(self.inc);
let xorshifted = (((old >> 18) ^ old) >> 27) as u32;
let rot = (old >> 59) as u32;
(xorshifted >> rot) | (xorshifted << ((!rot).wrapping_add(1) & 31))
}
 
fn next_float(&mut self) -> f64 {
(self.next_int() as f64) / ((1u64 << 32) as f64)
}
 
fn seed(&mut self, seed_state: u64, seed_sequence: u64) {
self.state = 0;
self.inc = (seed_sequence << 1) | 1;
self.next_int();
self.state = self.state.wrapping_add(seed_state);
self.next_int();
}
}
 
fn main() {
let mut rng = PCG32::new();
 
rng.seed(42, 54);
for _ in 0..5 {
println!("{}", rng.next_int());
}
 
println!();
 
let mut counts = [0; 5];
rng.seed(987654321, 1);
for _ in 0..100000 {
let j = (rng.next_float() * 5.0).floor() as usize;
counts[j] += 1;
}
 
println!("The counts for 100,000 repetitions are:");
for (i, count) in counts.iter().enumerate() {
println!(" {} : {}", i, count);
}
}
</syntaxhighlight>
{{out}}
<pre>
2707161783
2068313097
3122475824
2211639955
3215226955
 
The counts for 100,000 repetitions are:
0 : 20049
1 : 20022
2 : 20115
3 : 19809
4 : 20005
 
</pre>
 
=={{header|Scala}}==
{{trans|Java}}
<syntaxhighlight lang="Scala">
object PCG32 {
private val N = 6364136223846793005L
 
private var state = 0x853c49e6748fea9bL
private var inc = 0xda3e39cb94b95bdbL
 
def seed(seedState: Long, seedSequence: Long): Unit = {
state = 0
inc = (seedSequence << 1) | 1
nextInt()
state += seedState
nextInt()
}
 
def nextInt(): Int = {
val old = state
state = old * N + inc
val shifted = (((old >>> 18) ^ old) >>> 27).toInt
val rot = (old >>> 59).toInt
(shifted >>> rot) | (shifted << ((~rot + 1) & 31))
}
 
def nextFloat(): Double = {
val u = nextInt() & 0xffffffffL
u.toDouble / (1L << 32)
}
}
 
object Main extends App {
val r = PCG32
 
r.seed(42, 54)
println(Integer.toUnsignedString(r.nextInt()))
println(Integer.toUnsignedString(r.nextInt()))
println(Integer.toUnsignedString(r.nextInt()))
println(Integer.toUnsignedString(r.nextInt()))
println(Integer.toUnsignedString(r.nextInt()))
println()
 
val counts = Array(0, 0, 0, 0, 0)
r.seed(987654321, 1)
for (_ <- 1 to 100000) {
val j = Math.floor(r.nextFloat() * 5.0).toInt
counts(j) += 1
}
 
println("The counts for 100,000 repetitions are:")
for (i <- counts.indices) {
println(s" $i : ${counts(i)}")
}
}
</syntaxhighlight>
{{out}}
<pre>
2707161783
2068313097
3122475824
2211639955
3215226955
 
The counts for 100,000 repetitions are:
0 : 20049
1 : 20022
2 : 20115
3 : 19809
4 : 20005
 
</pre>
 
=={{header|Scheme}}==
{{trans|Ruby}}
 
<syntaxhighlight lang="scheme">(import (scheme small) (srfi 33))
 
(define PCG-DEFAULT-MULTIPLIER 6364136223846793005)
(define MASK64 (- (arithmetic-shift 1 64) 1))
(define MASK32 (- (arithmetic-shift 1 32) 1))
 
(define-record-type <pcg32-random> (make-pcg32-random-record) pcg32?
(state pcg32-state pcg32-state!)
(inc pcg32-inc pcg32-inc!))
 
(define (make-pcg32)
(define rng (make-pcg32-random-record))
(pcg32-seed rng 31415926 535897932)
rng)
 
(define (pcg32-seed rng init-state init-seq)
(pcg32-state! rng 0)
(pcg32-inc! rng
(bitwise-and
(bitwise-ior (arithmetic-shift init-seq 1) 1)
MASK64))
(pcg32-next-int rng)
(pcg32-state! rng (bitwise-and (+ (pcg32-state rng) init-state) MASK64))
(pcg32-next-int rng))
 
(define (pcg32-next-int rng)
(define xorshifted 0)
(define rot 0)
(define answer 0)
(define oldstate (pcg32-state rng))
(pcg32-state! rng
(bitwise-and
(+ (* oldstate PCG-DEFAULT-MULTIPLIER) (pcg32-inc rng))
MASK64))
(set! xorshifted (bitwise-xor (arithmetic-shift oldstate -18) oldstate))
(set! xorshifted (arithmetic-shift xorshifted -27))
(set! xorshifted (bitwise-and xorshifted MASK32))
(set! rot (bitwise-and (arithmetic-shift oldstate -59) MASK32))
(set! answer (bitwise-ior
(arithmetic-shift xorshifted (- rot))
(arithmetic-shift xorshifted (bitwise-and (- rot) 31))))
(set! answer (bitwise-and answer MASK32))
answer)
 
(define (pcg32-next-float rng)
(inexact (/ (pcg32-next-int rng) (arithmetic-shift 1 32))))
 
;; task
 
(define rng (make-pcg32))
(pcg32-seed rng 42 54)
(let lp ((i 0)) (when (< i 5)
(display (pcg32-next-int rng))(newline)
(lp (+ i 1))))
(newline)
 
(pcg32-seed rng 987654321 1)
(define vec (make-vector 5 0))
(let lp ((i 0)) (when (< i 100000)
(let ((j (exact (floor (* (pcg32-next-float rng) 5)))))
(vector-set! vec j (+ (vector-ref vec j) 1)))
(lp (+ i 1))))
(let lp ((i 0)) (when (< i 5)
(display i)
(display " : ")
(display (vector-ref vec i))
(newline)
(lp (+ i 1))))
</syntaxhighlight>
{{out}}
<pre>
2707161783
2068313097
3122475824
2211639955
3215226955
 
0 : 20049
1 : 20022
2 : 20115
3 : 19809
4 : 20005
</pre>
 
=={{header|Sidef}}==
{{trans|Perl}}
<syntaxhighlight lang="ruby">class PCG32(seed, incr) {
 
has state
 
define (
mask32 = (2**32 - 1),
mask64 = (2**64 - 1),
N = 6364136223846793005,
)
 
method init {
seed := 1
incr := 2
incr = (((incr << 1) | 1) & mask64)
state = (((incr + seed)*N + incr) & mask64)
}
 
method next_int {
var shift = ((((state >> 18) ^ state) >> 27) & mask32)
var rotate = ((state >> 59) & mask32)
state = ((state*N + incr) & mask64)
((shift >> rotate) | (shift << (32-rotate))) & mask32
}
 
method next_float {
self.next_int / (mask32+1)
}
}
 
say "Seed: 42, Increment: 54, first 5 values:";
var rng = PCG32(seed: 42, incr: 54)
say 5.of { rng.next_int }
 
say "\nSeed: 987654321, Increment: 1, values histogram:";
var rng = PCG32(seed: 987654321, incr: 1)
var histogram = Bag(1e5.of { floor(5*rng.next_float) }...)
histogram.pairs.sort.each { .join(": ").say }</syntaxhighlight>
{{out}}
<pre>
Seed: 42, Increment: 54, first 5 values:
[2707161783, 2068313097, 3122475824, 2211639955, 3215226955]
 
Seed: 987654321, Increment: 1, values histogram:
0: 20049
1: 20022
2: 20115
3: 19809
4: 20005
</pre>
 
=={{header|Standard ML}}==
<syntaxhighlight lang="sml">type pcg32 = LargeWord.word * LargeWord.word
 
local
infix 5 >>
val op >> = LargeWord.>>
and m = 0w6364136223846793005 : LargeWord.word
and rotate32 = fn a as (x, n) =>
Word32.orb (Word32.>> a, Word32.<< (x, Word.andb (~ n, 0w31)))
in
fun pcg32Init (seed, seq) : pcg32 =
let
val inc = LargeWord.<< (LargeWord.fromInt seq, 0w1) + 0w1
in
((LargeWord.fromInt seed + inc) * m + inc, inc)
end
fun pcg32Random ((state, inc) : pcg32) : Word32.word * pcg32 = (
rotate32 (
Word32.xorb (
Word32.fromLarge (state >> 0w27),
Word32.fromLarge (state >> 0w45)),
Word.fromLarge (state >> 0w59)),
(state * m + inc, inc))
end</syntaxhighlight>
;Test code<nowiki>:</nowiki>
<syntaxhighlight lang="sml">fun test1 (rand, state) =
(print (Word32.fmt StringCvt.DEC rand ^ "\n"); state)
 
local
val prependFormatted =
fn (i, v, lst) => Int.toString i ^ ": " ^ Int.toString v :: lst
and counts = IntArray.array (5, 0)
in
fun test2 (rand, state) =
let
val i = LargeWord.toInt (LargeWord.>> (0w5 * Word32.toLarge rand, 0w32))
in
IntArray.update (counts, i, IntArray.sub (counts, i) + 1); state
end
fun test2res () =
IntArray.foldri prependFormatted [] counts
end
 
fun doTimes (_, 0, state) = state
| doTimes (f, n, state) = doTimes (f, n - 1, f state)
 
val _ = doTimes (test1 o pcg32Random, 5, pcg32Init (42, 54))
 
val _ = doTimes (test2 o pcg32Random, 100000, pcg32Init (987654321, 1))
val () = print ("\n" ^ ((String.concatWith ", " o test2res) ()) ^ "\n")</syntaxhighlight>
{{out}}
<pre>2707161783
2068313097
3122475824
2211639955
3215226955
 
0: 20049, 1: 20022, 2: 20115, 3: 19809, 4: 20005</pre>
 
=={{header|Tcl}}==
{{trans|C}}
<syntaxhighlight lang="Tcl">
proc uint32 {n} {
return [expr {$n & 0xffffffff}]
}
 
proc uint64 {n} {
return [expr {$n & 0xffffffffffffffff}]
}
 
set N 6364136223846793005
set state 0x853c49e6748fea9b
set inc 0xda3e39cb94b95bdb
 
proc pcg32_seed {seed_state seed_sequence} {
global state inc
set state 0
set inc [expr {($seed_sequence << 1) | 1}]
pcg32_int
set state [expr {$state + $seed_state}]
pcg32_int
}
 
proc pcg32_int {} {
global state N inc
set old $state
set state [uint64 [expr {$old * $N + $inc}]]
set shifted [uint32 [expr {(($old >> 18) ^ $old) >> 27}]]
set rot [uint32 [expr {$old >> 59}]]
return [uint32 [expr {($shifted >> $rot) | ($shifted << ((~$rot + 1) & 31))}]]
}
 
proc pcg32_float {} {
return [expr {1.0 * [pcg32_int] / (1 << 32)}]
}
 
# -------------------------------------------------------------------
 
pcg32_seed 42 54
puts [pcg32_int]
puts [pcg32_int]
puts [pcg32_int]
puts [pcg32_int]
puts [pcg32_int]
puts ""
 
set counts {0 0 0 0 0}
pcg32_seed 987654321 1
for {set i 1} {$i <= 100000} {incr i} {
set j [expr {int([pcg32_float] * 5.0) + 1}]
lset counts [expr {$j - 1}] [expr {[lindex $counts [expr {$j - 1}]] + 1}]
}
 
puts "The counts for 100,000 repetitions are:"
foreach idx {0 1 2 3 4} {
puts " $idx: [lindex $counts $idx]"
}
</syntaxhighlight>
{{out}}
<pre>
2707161783
2068313097
3122475824
2211639955
3215226955
 
The counts for 100,000 repetitions are:
0: 20049
1: 20022
2: 20115
3: 19809
4: 20005
 
</pre>
 
 
=={{header|uBasic/4tH}}==
{{trans|C}}
uBasic/4tH only supports signed integers - so floating point is out of the question. It also requires clipping some integers to 32 bits in order to make this work.
<syntaxhighlight lang="text">' ** NOTE: this requires a 64-bit uBasic. **
 
If Info("wordsize") < 64 Then Print "This program requires a 64-bit uBasic" : End
 
n = 6364136223846793005
s = 377257722939173531 + 9223372036854775807 + 1
i = 6502698458505894875 + 9223372036854775807 + 1
 
Proc _PCG32Seed(42, 54);
Print FUNC(_PCG32Int)
Print FUNC(_PCG32Int)
Print FUNC(_PCG32Int)
Print FUNC(_PCG32Int)
Print FUNC(_PCG32Int)
End
_PCG32Int
Local (3)
a@ = s
s = (a@ * n) + i
b@ = And(Shl(Xor(Shl(a@, -18), a@), -27), 4294967295)
c@ = And(Shl(a@, -59), 4294967295)
Return (And(Or(Shl(b@, -c@), Shl(b@, And((Not(c@) + 1), 31))), 4294967295))
_PCG32Seed
Param (2)
s = 0
i = Or(Shl(b@, 1), 1)
Proc _PCG32Int
s = s + a@
Proc _PCG32Int
Return</syntaxhighlight>
{{Out}}
<pre>2707161783
2068313097
3122475824
2211639955
3215226955
 
0 OK, 0:391</pre>
 
=={{header|Wren}}==
Line 1,080 ⟶ 2,654:
{{libheader|Wren-big}}
As Wren doesn't have a 64-bit integer type, we use BigInt instead.
<langsyntaxhighlight ecmascriptlang="wren">import "./big" for BigInt
 
var Const = BigInt.new("6364136223846793005")
Line 1,122 ⟶ 2,696:
}
System.print("\nThe counts for 100,000 repetitions are:")
for (i in 0..4) System.print(" %(i) : %(counts[i])")</langsyntaxhighlight>
 
{{out}}
9,482

edits