summaryrefslogtreecommitdiff
path: root/randomunit.pas
diff options
context:
space:
mode:
authorErich Eckner <git@eckner.net>2015-07-10 15:10:15 +0200
committerErich Eckner <git@eckner.net>2015-07-10 15:20:53 +0200
commitffb35ffece4f0239cf9fcecbfba5329d7b5dc98d (patch)
treebc07a061ee40ed18106cd5a13528d074d1228960 /randomunit.pas
parentaddd58de0c9311f791355231d53e4b280ff3537d (diff)
downloadunits-ffb35ffece4f0239cf9fcecbfba5329d7b5dc98d.tar.xz
neue Dateien: matheunit.pas, mlockunit.pas, mystringlistunit.pas,
pseudohadamard.pas, randomunit.pas, systemunit.pas
Diffstat (limited to 'randomunit.pas')
-rw-r--r--randomunit.pas80
1 files changed, 80 insertions, 0 deletions
diff --git a/randomunit.pas b/randomunit.pas
new file mode 100644
index 0000000..2b665f0
--- /dev/null
+++ b/randomunit.pas
@@ -0,0 +1,80 @@
+unit randomunit;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils;
+
+type
+ tMersenneTwister = class
+ private
+ state: array[0..623] of longword;
+ index: longint;
+ public
+ procedure init(seed: longword);
+ function extract_number: longword;
+ function random(ma: longword): longword; overload;
+ function random: extended; overload;
+ procedure generate_numbers;
+ end;
+
+implementation
+
+// tMersenneTwister ************************************************************
+
+procedure tMersenneTwister.init(seed: longword);
+var
+ i: longint;
+begin
+ index:=0;
+ state[0]:=seed;
+ for i:=1 to 623 do
+ state[i]:=longword($ffffffff and (qword(1812433253) * qword(state[i-1] xor state[i-1] shr 30) + i)); // 0x6c078965
+end;
+
+function tMersenneTwister.extract_number: longword;
+begin
+ if index=0 then
+ generate_numbers;
+
+ result:=state[index];
+ result:=result xor (result shr 11);
+ result:=result xor longword(qword(result shl 7) and 2636928640); // 0x9d2c5680
+ result:=result xor longword(qword(result shl 15) and 4022730752); // 0xefc60000
+ result:=result xor (result shr 18);
+
+ index := (index + 1) mod 624;
+end;
+
+function tMersenneTwister.random(ma: longword): longword;
+var
+ i: longword;
+begin
+ repeat
+ i:=extract_number;
+ until i<((high(longword)+1) div qword(ma))*ma;
+ result:=i mod ma;
+end;
+
+function tMersenneTwister.random: extended;
+begin
+ result:=(extract_number/(high(longword)+1) + extract_number)/(high(longword)+1);
+end;
+
+procedure tMersenneTwister.generate_numbers;
+var
+ i,y: longint;
+begin
+ for i:=0 to 623 do begin
+ y:=longint((state[i] and $80000000) or // bit 31 (32nd bit) of MT[i]
+ (state[(i+1) mod 624] and $7fffffff)); // bits 0-30 (first 31 bits) of MT[...]
+ state[i]:=state[(i + 397) mod 624] xor (y shr 1);
+ if odd(y) then
+ state[i]:=longword(state[i] xor 2567483615); // 0x9908b0df
+ end;
+end;
+
+end.
+