Inzwischen sind die Funktionen "auch" als Pure-Pascal verfügbar (für andere Platformen wo dieser Assembler nicht läuft)
und was ich grad bemerkte und als besonders praktisch empfand, wurden dort irgendwann zwei Variablen eingebaut, so dass man da ein eigenes Random (IntRandom) und Randomize registrieren und es somit auch "überall" im Delphi austauschen kann.
PS: Das aus #30 noch ein bissl zusammengefasst, dann kommt das bei raus.
Delphi-Quellcode:
function ra(aRange: Integer): Integer;
begin
RandSeed := RandSeed * 134775813 + 1; // 3*17*131*20173
Result := (Int64(aRange) * RandSeed) shr 32; // aka Result := MulDiv(aRange, RandSeed, $100000000);
end;
Aber die Grundlagen des "deterministic linear congruential generator with 134775813 as a and 1 as c" haben sich nicht geändert.
Das ist seit über 20 Jahren konstant. Nur wurde vor längerer Zeit mal das GetTickCount gegen QueryPerformanceCounter im Randomize ersetzt, womit ein "falsch" benutztes und zu oft/schnell aufgerufenes Randomize keine großen Nachteile bringt.
Delphi-Quellcode:
type
TRandom32Proc =
function: UInt32;
TRandomizeProc =
procedure(NewSeed: UInt64);
function DefaultRandom32: UInt32;
procedure DefaultRandomize(NewSeed: UInt64);
var
Random32Proc: TRandom32Proc = DefaultRandom32;
RandomizeProc: TRandomizeProc = DefaultRandomize;
procedure Randomize;
function Random(
const ARange: Integer): Integer;
overload;
function Random: Extended;
overload;
function DefaultRandom32: UInt32;
{$IFDEF PUREPASCAL}
begin
Result := UInt32(RandSeed) * $08088405 + 1;
RandSeed := Result
end;
{$ELSE !PUREPASCAL}
asm
{ <-EAX Result }
{$IFDEF PIC}
PUSH EBX
CALL GetGOT
MOV EBX,EAX
MOV ECX,[EBX].RandSeed
IMUL EAX,[ECX],08088405H
INC EAX
MOV [ECX],EAX
POP EBX
{$ELSE !PIC}
IMUL EAX,RandSeed,08088405H
INC EAX
MOV RandSeed,EAX
{$ENDIF !PIC}
end;
{$ENDIF !PUREPASCAL}
function Random(
const ARange: Integer): Integer;
{$IFDEF PUREPASCAL}
var
Temp: UInt32;
begin
Temp := Random32Proc;
Result := (UInt64(UInt32(ARange)) * UInt64(Temp))
shr 32;
end;
{$ELSE !PUREPASCAL}
asm
{ ->EAX Range }
{ <-EAX Result }
{$IFDEF PIC}
PUSH EBX
PUSH EAX
...