Pseudo-random numbers/Splitmix64: Difference between revisions
Content added Content deleted
(F# impl) |
No edit summary |
||
Line 101: | Line 101: | ||
16408922859458223821 |
16408922859458223821 |
||
[0 = 20027, 1 = 19892, 2 = 20073, 3 = 19978, 4 = 20030] |
[0 = 20027, 1 = 19892, 2 = 20073, 3 = 19978, 4 = 20030] |
||
</pre> |
|||
=={{header|Ada}}== |
|||
Ada conversion of Next_float * 5.0 to an integer value resulted in some values of 5 which would have caused a buffer overflow in the counting array. The fix was to truncate Next_float * 5.0 as a floating point value and convert that value to an integer. Upon doing this the counts of each array element become 20073, indicating there are an equal number values in each portion of the random number range. |
|||
The random number functions are written in a stand-alone package. The package is split into a package specification defining the interfaces to the public subprograms and a body containing the implementation of the random number generator. |
|||
'''package specification:''' |
|||
<lang Ada>with Interfaces; use Interfaces; |
|||
package Random_Splitmix64 is |
|||
function next_Int return Unsigned_64; |
|||
function next_float return Float; |
|||
procedure Set_State (Seed : in Unsigned_64); |
|||
end Random_Splitmix64;</lang> |
|||
'''package body:''' |
|||
<lang Ada>package body Random_Splitmix64 is |
|||
Internal : Unsigned_64 := 1234567; |
|||
-------------- |
|||
-- next_Int -- |
|||
-------------- |
|||
function next_Int return Unsigned_64 is |
|||
Z : Unsigned_64; |
|||
begin |
|||
Internal := Internal + 16#9e3779b97f4a7c15#; |
|||
Z := Internal; |
|||
Z := (Z xor Shift_Right(Z, 30)) * 16#bf58476d1ce4e5b9#; |
|||
Z := (Z xor Shift_Right(Z, 27)) * 16#94d049bb133111eb#; |
|||
return Z xor Shift_Right(Z, 31); |
|||
end next_Int; |
|||
---------------- |
|||
-- next_float -- |
|||
---------------- |
|||
function next_float return Float is |
|||
begin |
|||
return float(next_int) / (2.0 ** 64); |
|||
end next_float; |
|||
--------------- |
|||
-- Set_State -- |
|||
--------------- |
|||
procedure Set_State (Seed : in Unsigned_64) is |
|||
begin |
|||
Internal := Seed; |
|||
end Set_State; |
|||
end Random_Splitmix64;</lang> |
|||
'''Main procedure:''' |
|||
<lang Ada>with Interfaces; use Interfaces; |
|||
with Random_Splitmix64; use Random_Splitmix64; |
|||
with Ada.Text_IO; use Ada.Text_IO; |
|||
procedure Main is |
|||
subtype idx is Integer range 0 .. 4; |
|||
type answer_arr is array (idx) of Unsigned_64; |
|||
Vec : answer_arr := (others => 0); |
|||
J : idx; |
|||
fj : Float; |
|||
begin |
|||
Set_State (1_234_567); |
|||
for I in 1 .. 5 loop |
|||
Put (Unsigned_64'Image (next_Int)); |
|||
New_Line; |
|||
end loop; |
|||
Set_State (987_654_321); |
|||
for I in 1 .. 100_000 loop |
|||
fj := Float'Truncation (next_float * 5.0); |
|||
J := idx (fj); |
|||
Vec (J) := Vec (J) + 1; |
|||
end loop; |
|||
for I in Vec'Range loop |
|||
Put_Line (I'Image & ":" & Unsigned_64'Image (Vec (J))); |
|||
end loop; |
|||
end Main;</lang> |
|||
{{out}} |
|||
<pre> |
|||
6457827717110365317 |
|||
3203168211198807973 |
|||
9817491932198370423 |
|||
4593380528125082431 |
|||
16408922859458223821 |
|||
0: 20073 |
|||
1: 20073 |
|||
2: 20073 |
|||
3: 20073 |
|||
4: 20073 |
|||
</pre> |
</pre> |
||