Pseudo-random numbers/PCG32: Difference between revisions

m
(Add Rust implementation)
m (→‎{{header|Wren}}: Minor tidy)
 
(6 intermediate revisions by one other user not shown)
Line 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++}}==
Line 508 ⟶ 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 1,153 ⟶ 1,326:
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}}==
Line 2,275 ⟶ 2,526:
 
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}}==
Line 2,326 ⟶ 2,654:
{{libheader|Wren-big}}
As Wren doesn't have a 64-bit integer type, we use BigInt instead.
<syntaxhighlight lang="ecmascriptwren">import "./big" for BigInt
 
var Const = BigInt.new("6364136223846793005")
9,476

edits