Pseudo-random numbers/PCG32: Difference between revisions

no edit summary
No edit summary
Line 70:
 
* Show your output here, on this page.
 
 
=={{header|Ada}}==
Ada solution using a package to encapsulate the PCG32 algorithm.
<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;
</lang>
 
<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;
</lang>
 
<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;
</lang>
{{output}}
<pre>
2707161783
2068313097
3122475824
2211639955
3215226955
 
0 : 20049
1 : 20022
2 : 20115
3 : 19809
4 : 20005
</pre>
 
 
82

edits