Pseudo-random numbers/PCG32: Difference between revisions

add Standard ML
(add Standard ML)
Line 1,405:
4: 20005
</pre>
 
=={{header|Standard ML}}==
<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</lang>
;Test code<nowiki>:</nowiki>
<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")</lang>
{{out}}
<pre>2707161783
2068313097
3122475824
2211639955
3215226955
 
0: 20049, 1: 20022, 2: 20115, 3: 19809, 4: 20005</pre>
 
=={{header|Wren}}==
559

edits