Код: Выделить всё
type
TDotNetRandom = class
private
const
MBIG = 2147483647; // int.MaxValue
MSEED = 161803398;
MZ = 0;
var
SeedArray: array[0..55] of Integer;
inext, inextp: Integer;
public
constructor Create(Seed: Integer);
function Sample: Double; // [0.0, 1.0)
function Next: Integer; overload;
function Next(MaxValue: Integer): Integer; overload;
function Next(MinValue, MaxValue: Integer): Integer; overload;
end;
constructor TDotNetRandom.Create(Seed: Integer);
var
ii, mj, mk, i, k: Integer;
subtraction: Integer;
begin
if Seed = Low(Integer) then
subtraction := High(Integer)
else
subtraction := Abs(Seed);
mj := MSEED - subtraction;
SeedArray[55] := mj;
mk := 1;
for i := 1 to 54 do
begin
ii := (21 * i) mod 55;
SeedArray[ii] := mk;
mk := mj - mk;
if mk < 0 then
mk := mk + MBIG;
mj := SeedArray[ii];
end;
// Важно: 4 цикла, НЕ 5!
for k := 1 to 4 do
for i := 1 to 55 do
begin
SeedArray[i] := SeedArray[i] - SeedArray[1 + (i + 30) mod 55];
if SeedArray[i] < 0 then
SeedArray[i] := SeedArray[i] + MBIG;
end;
inext := 0;
inextp := 21;
end;
function TDotNetRandom.Sample: Double;
var
temp: Integer;
begin
Inc(inext);
if inext >= 56 then inext := 1;
Inc(inextp);
if inextp >= 56 then inextp := 1;
temp := SeedArray[inext] - SeedArray[inextp];
if temp < 0 then
temp := temp + MBIG;
SeedArray[inext] := temp;
Result := temp * (1.0 / MBIG);
end;
function TDotNetRandom.Next: Integer;
begin
Result := Trunc(Sample * MBIG);
end;
function TDotNetRandom.Next(MaxValue: Integer): Integer;
begin
if MaxValue <= 0 then
Exit(0);
Result := Trunc(Sample * MaxValue);
end;
function TDotNetRandom.Next(MinValue, MaxValue: Integer): Integer;
begin
if MaxValue <= MinValue then
Exit(MinValue);
Result := MinValue + Next(MaxValue - MinValue);
end;
