Pseudo-random numbers/PCG32: Difference between revisions

m
(Added uBasic/4tH version)
m (→‎{{header|Wren}}: Minor tidy)
(14 intermediate revisions by 5 users not shown)
Line 75:
{{trans|Python}}
 
<langsyntaxhighlight lang="11l">T PCG32
UInt64 state, inc
 
Line 83:
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)
Line 104:
L 100'000
hist[Int(random_gen.next_float() * 5)]++
print(hist)</langsyntaxhighlight>
 
{{out}}
Line 118:
=={{header|Ada}}==
Ada solution using a package to encapsulate the PCG32 algorithm.
<langsyntaxhighlight Adalang="ada">with Interfaces; use Interfaces;
 
package random_pcg32 is
Line 125:
procedure Seed (seed_state : Unsigned_64; seed_sequence : Unsigned_64);
end random_pcg32;
</syntaxhighlight>
</lang>
 
<langsyntaxhighlight Adalang="ada">package body random_pcg32 is
 
State : Unsigned_64 := 0;
Line 185:
 
end random_pcg32;
</syntaxhighlight>
</lang>
 
<langsyntaxhighlight Adalang="ada">with Ada.Text_Io; use ADa.Text_io;
with Interfaces; use Interfaces;
with random_pcg32; use random_pcg32;
Line 212:
end Main_P;
</syntaxhighlight>
</lang>
{{output}}
<pre>
Line 230:
=={{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 286:
print( ( newline ) )
END
END</langsyntaxhighlight>
{{out}}
<pre>
Line 299:
=={{header|C}}==
{{trans|Go}}
<langsyntaxhighlight lang="c">#include <math.h>
#include <stdint.h>
#include <stdio.h>
Line 352:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>2707161783
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++}}==
{{trans|C}}
<langsyntaxhighlight lang="cpp">#include <array>
#include <iostream>
#include <math.h>
 
class PCG32 {
Line 423 ⟶ 507:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>2707161783
Line 440 ⟶ 524:
=={{header|D}}==
{{trans|C++}}
<langsyntaxhighlight lang="d">import std.math;
import std.stdio;
 
Line 493 ⟶ 577:
writeln(" ", i, " : ", v);
}
}</langsyntaxhighlight>
{{out}}
<pre>2707161783
Line 507 ⟶ 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 514 ⟶ 688:
{{libheader| System.Generics.Collections}}
{{Trans|Python}}
<syntaxhighlight lang="delphi">
<lang Delphi>
program PCG32_test;
 
Line 635 ⟶ 809:
Readln;
end.
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 654 ⟶ 828:
=={{header|F_Sharp|F#}}==
===The Functions===
<langsyntaxhighlight lang="fsharp">
// PCG32. Nigel Galloway: August 13th., 2020
let N=6364136223846793005UL
Line 660 ⟶ 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 673 ⟶ 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 714 ⟶ 889:
987654321 1 [ seed ] keepdd
100,000 [ dup next-float 5 * >integer ] replicate nip
histogram .</langsyntaxhighlight>
{{out}}
<pre>
Line 727 ⟶ 902:
=={{header|Go}}==
{{trans|Python}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 777 ⟶ 952:
fmt.Printf(" %d : %d\n", i, counts[i])
}
}</langsyntaxhighlight>
 
{{out}}
Line 799 ⟶ 974:
Implement given algorithm as an instance of <code>RandomGen</code> class.
 
<langsyntaxhighlight lang="haskell">import Data.Bits
import Data.Word
import System.Random
Line 826 ⟶ 1,001:
randoms' g = unfoldr (pure . next) g
 
toFloat n = fromIntegral n / (2^32 - 1)</langsyntaxhighlight>
 
Direct usage of generator:
Line 843 ⟶ 1,018:
*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++}}
<langsyntaxhighlight lang="java">public class PCG32 {
private static final long N = 6364136223846793005L;
 
Line 896 ⟶ 1,113:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>2707161783
Line 913 ⟶ 1,130:
=={{header|Julia}}==
{{trans|Python}}
<langsyntaxhighlight lang="julia">const mask32, CONST = 0xffffffff, UInt(6364136223846793005)
 
mutable struct PCG32
Line 959 ⟶ 1,176:
 
testPCG32()
</langsyntaxhighlight>{{out}}
<pre>
2707161783
Line 973 ⟶ 1,190:
{{trans|C++}}
Requires the experimental unsigned feature for integer types
<langsyntaxhighlight lang="scala">import kotlin.math.floor
 
class PCG32 {
Line 1,026 ⟶ 1,243:
println(" %d : %d".format(iv.index, iv.value))
}
}</langsyntaxhighlight>
{{out}}
<pre>2707161783
Line 1,043 ⟶ 1,260:
=={{header|Lua}}==
{{trans|C}}
<langsyntaxhighlight lang="lua">function uint32(n)
return n & 0xffffffff
end
Line 1,095 ⟶ 1,312:
for i=1,5 do
print(" " .. (i - 1) .. ": " .. counts[i])
end</langsyntaxhighlight>
{{out}}
<pre>2707161783
Line 1,109 ⟶ 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}}==
<langsyntaxhighlight Nimlang="nim">import algorithm, sequtils, strutils, tables
 
const N = 6364136223846793005u64
Line 1,146 ⟶ 1,441:
for _ in 1..100_000:
counts.inc int(gen.nextFloat() * 5)
echo sorted(toSeq(counts.pairs)).mapIt($it[0] & ": " & $it[1]).join(", ")</langsyntaxhighlight>
 
{{out}}
Line 1,156 ⟶ 1,451:
 
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';
Line 1,203 ⟶ 1,541:
$rng = PCG32->new(seed => 987654321, incr => 1);
$h{int 5 * $rng->next_float}++ for 1 .. 100_000;
say "$_ $h{$_}" for sort keys %h;</langsyntaxhighlight>
{{out}}
<pre>Seed: 42, Increment: 54, first 5 values:
Line 1,224 ⟶ 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)
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<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>
<span style="color: #7060A8;">set_rand</span><span style="color: #0000FF;">(</span><span style="color: #000000;">42</span><span style="color: #0000FF;">)</span>
Line 1,236 ⟶ 1,574:
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">s</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 1,248 ⟶ 1,586:
</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, not that there is anywhere near enough work being done here to make that measureable.
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">include</span> <span style="color: #004080;">mpfr</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
Line 1,302 ⟶ 1,640:
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">r</span>
<!--</langsyntaxhighlight>-->
{{out}}
<pre>
Line 1,316 ⟶ 1,654:
 
===Python: As class===
<langsyntaxhighlight lang="python">mask64 = (1 << 64) - 1
mask32 = (1 << 32) - 1
CONST = 6364136223846793005
Line 1,362 ⟶ 1,700:
for i in range(100_000):
hist[int(random_gen.next_float() *5)] += 1
print(hist)</langsyntaxhighlight>
 
{{out}}
Line 1,374 ⟶ 1,712:
===Python: As generator===
 
<langsyntaxhighlight lang="python">def pcg32(seed_state=None, seed_sequence=None, as_int=True):
def next_int():
"return random 32 bit unsigned int"
Line 1,406 ⟶ 1,744:
for i in islice(pcg32(987654321, 1, as_int=False), 100_000):
hist[int(i * 5)] += 1
print(hist)</langsyntaxhighlight>
 
{{out}}
Line 1,422 ⟶ 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,463 ⟶ 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,487 ⟶ 1,825:
DON'T use Rexx, however, for this type of problem unless you take the time spent
for some Java coffees!
<langsyntaxhighlight lang="rexx">Numeric Digits 40
N = 6364136223846793005
state = x2d('853c49e6748fea9b',16)
Line 1,777 ⟶ 2,115:
b=b||bits.c
End
Return b </langsyntaxhighlight>
{{out}}
<pre>
Line 1,796 ⟶ 2,134:
=={{header|Ruby}}==
{{trans|Python}}
<langsyntaxhighlight Rubylang="ruby">class PCG32
MASK64 = (1 << 64) - 1
MASK32 = (1 << 32) - 1
Line 1,830 ⟶ 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,840 ⟶ 2,178:
</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}}
 
<langsyntaxhighlight Schemelang="scheme">(import (scheme small) (srfi 33))
 
(define PCG-DEFAULT-MULTIPLIER 6364136223846793005)
Line 1,912 ⟶ 2,400:
(newline)
(lp (+ i 1))))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,927 ⟶ 2,415:
4 : 20005
</pre>
 
 
=={{header|Sidef}}==
{{trans|Perl}}
<langsyntaxhighlight lang="ruby">class PCG32(seed, incr) {
 
has state
Line 1,967 ⟶ 2,454:
var rng = PCG32(seed: 987654321, incr: 1)
var histogram = Bag(1e5.of { floor(5*rng.next_float) }...)
histogram.pairs.sort.each { .join(": ").say }</langsyntaxhighlight>
{{out}}
<pre>
Line 1,982 ⟶ 2,469:
 
=={{header|Standard ML}}==
<langsyntaxhighlight lang="sml">type pcg32 = LargeWord.word * LargeWord.word
 
local
Line 2,004 ⟶ 2,491:
Word.fromLarge (state >> 0w59)),
(state * m + inc, inc))
end</langsyntaxhighlight>
;Test code<nowiki>:</nowiki>
<langsyntaxhighlight lang="sml">fun test1 (rand, state) =
(print (Word32.fmt StringCvt.DEC rand ^ "\n"); state)
 
Line 2,030 ⟶ 2,517:
 
val _ = doTimes (test2 o pcg32Random, 100000, pcg32Init (987654321, 1))
val () = print ("\n" ^ ((String.concatWith ", " o test2res) ()) ^ "\n")</langsyntaxhighlight>
{{out}}
<pre>2707161783
Line 2,039 ⟶ 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}}==
{{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
Line 2,076 ⟶ 2,640:
s = s + a@
Proc _PCG32Int
Return</langsyntaxhighlight>
{{Out}}
<pre>2707161783
Line 2,085 ⟶ 2,649:
 
0 OK, 0:391</pre>
 
=={{header|Wren}}==
{{trans|Python}}
{{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 2,131 ⟶ 2,696:
}
System.print("\nThe counts for 100,000 repetitions are:")
for (i in 0..4) System.print(" %(i) : %(counts[i])")</langsyntaxhighlight>
 
{{out}}
9,485

edits