Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Delphi 11 kein RandomRange für 64-bits? (https://www.delphipraxis.net/210429-delphi-11-kein-randomrange-fuer-64-bits.html)

softtouch 23. Apr 2022 08:28

Delphi 11 kein RandomRange für 64-bits?
 
Ich suche eine RandomRange Funktion die mit int64 anstatt integer arbeitet.
Habe leider bisher nichts gefunden.
Ich muss eine Zufallszahl zwischen 100000 und 9999999999 erzeugen.

Andreas13 23. Apr 2022 09:03

AW: Delphi 11 kein RandomRange für 64-bits?
 
Hallo Softtouch,
Du kannst die Routine System.Mathe.RandomRange(..) einfach abwandeln:
Delphi-Quellcode:
Function RandomRange(Const AFrom, ATo: UInt64): UInt64; Overload;
Begin
  IF AFrom > ATo Then
    Result:= Random(AFrom - ATo) + ATo
  Else
    Result:= Random(ATo - AFrom) + AFrom;
End;
Da das Result von Random eine Extended-Zahl ist, hast Du genug (bis zu 18..19) zufällige Ziffern, was knapp auch für den obersten Bereich von UInt64 (9223372036854775810) ausreichen dürfte.

Grüße, Andreas

[Edit]: Für Deinen Zahlenbereich zwischen 100000 und 9999999999 reicht es alle mal.

softtouch 23. Apr 2022 09:14

AW: Delphi 11 kein RandomRange für 64-bits?
 
Zitat:

Zitat von Andreas13 (Beitrag 1504999)
Hallo Softtouch,
Du kannst die Routine System.Mathe.RandomRange(..) einfach abwandeln:
Delphi-Quellcode:
Function RandomRange(Const AFrom, ATo: UInt64): UInt64; Overload;
Begin
  IF AFrom > ATo Then
    Result:= Random(AFrom - ATo) + ATo
  Else
    Result:= Random(ATo - AFrom) + AFrom;
End;
Da das Result von Random eine Extended-Zahl ist, hast Du genug (bis zu 18..19) zufällige Ziffern, was knapp auch für den obersten Bereich von UInt64 (9223372036854775810) ausreichen dürfte.

Grüße, Andreas

[Edit]: Für Deinen Zahlenbereich zwischen 100000 und 9999999999 reicht es alle mal.

Das erzeugt einen range check error, da ato-afrom immer noch mehr als ein integer ist.

Andreas13 23. Apr 2022 09:19

AW: Delphi 11 kein RandomRange für 64-bits?
 
Sorry, in der Tat. Ich habe es leider nur in der Nähe Deines oberen Breichs
Delphi-Quellcode:
Von:= 9999999999 - 500;
Bis:= 9999999999;
getestet. :oops:

Andreas

Uwe Raabe 23. Apr 2022 09:41

AW: Delphi 11 kein RandomRange für 64-bits?
 
Vielleicht klappt dies besser:
Delphi-Quellcode:
Function RandomRange(Const AFrom, ATo: UInt64): UInt64;
Begin
  Result:= Round(Random*(ATo - AFrom)) + AFrom;
End;

KodeZwerg 23. Apr 2022 09:57

AW: Delphi 11 kein RandomRange für 64-bits?
 
Vor Jahren irgendwo gefunden. Es leistete gute Dienste.

Delphi-Quellcode:
var
  vLehmerRandSeed64: Int64 = 0;
  vLehmerMultiplierA64: Int64 = 636413622384679305;
  vLehmerAdditiveConstantC64: Int64 = $1;

procedure SingleAdd(const A: LongWord; const B: LongWord; const CarryIn: LongWord; var Sum: LongWord; var CarryOut: LongWord);
var
  Temp: array [0 .. 1] of LongWord;
begin
  UInt64(Temp) := UInt64(A) + UInt64(B) + UInt64(CarryIn);
  Sum := Temp[0];
  CarryOut := Temp[1];
end;

function LehmerRandom64(ParaLehmerModulesM64: int64): int64;
var
  A: array [0 .. 1] of LongWord;
  B: array [0 .. 1] of LongWord;
  C: array [0 .. 3] of LongWord;
  vAindex: LongWord;
  vBindex: LongWord;
  vCindex: LongWord;
  vTransport: array [0 .. 1] of LongWord;
  vTransport1Index: LongWord;
  vTransport2Index: LongWord;
begin
{$RANGECHECKS OFF}
{$OVERFLOWCHECKS OFF}
  vLehmerRandSeed64 := vLehmerRandSeed64 * vLehmerMultiplierA64;
  vLehmerRandSeed64 := vLehmerRandSeed64 + vLehmerAdditiveConstantC64;
  C[0] := 0;
  C[1] := 0;
  C[2] := 0;
  C[3] := 0;
  Int64(A) := ParaLehmerModulesM64;
  Int64(B) := vLehmerRandSeed64;
  for vBindex := 0 to 1 do
  begin
    vTransport[0] := 0;
    vTransport[1] := 0;
    for vAindex := 0 to 1 do
    begin
      vCindex := vAindex + vBindex;
      Uint64(vTransport) := Uint64(A[vAindex]) * Uint64(B[vBindex]);
      for vTransport1Index := vCindex to 4 - 1 do
      begin
        if vTransport[0] = 0 then
          Break;
        SingleAdd(C[vTransport1Index], vTransport[0], 0, C[vTransport1Index], vTransport[0]);
      end;
      for vTransport2Index := vCindex + 1 to 4 - 1 do
      begin
        if vTransport[1] = 0 then
          Break;
        SingleAdd(C[vTransport2Index], vTransport[1], 0, C[vTransport2Index], vTransport[1]);
      end;
    end;
  end;
  Result := Int64(Pointer(@C[2])^);
{$OVERFLOWCHECKS ON}
{$RANGECHECKS ON}
end;

function RandomRange64(const AFrom, ATo: Int64): Int64;
begin
  if AFrom > ATo then
    Result := LehmerRandom64(AFrom - ATo) + ATo
  else
    Result := LehmerRandom64(ATo - AFrom) + AFrom;
end;
Man muss nur im Hinterkopf haben das erst ab dem zweiten Durchlauf die Zahlen variieren.

himitsu 23. Apr 2022 10:01

AW: Delphi 11 kein RandomRange für 64-bits?
 
Zitat:

Da das Result von Random eine Extended-Zahl ist, hast Du genug (bis zu 18..19) zufällige Ziffern, was knapp auch für den obersten Bereich von UInt64 (9223372036854775810) ausreichen dürfte.
So ganz stimmt es nicht.
Intern wird der Extended aus einem Int32 generiert, also entspricht es nur einem Single.

In diesem Fall würde ich zwei Mal Random verwenden, wenn Abs(ATo-AFrom) größer MaxInt ist.
Am Einfachsten den Abs(ATo-AFrom) halbieren, also die Bits, für das Random verwenden und es multiplizeren.

Uwe Raabe 23. Apr 2022 10:42

AW: Delphi 11 kein RandomRange für 64-bits?
 
Probleme bereiten könnte die Skalierung auf den Range. Bei 32-Bit wird das im 64-Bit Bereich erledigt. Für 64-Bit müsste dann 128-Bit Arithmetik verwendet werden. Ein simples Teilen und Zusammensetzen von zwei 32-Bit Randoms wird nicht so richtig funktionieren.

peterbelow 23. Apr 2022 16:27

AW: Delphi 11 kein RandomRange für 64-bits?
 
Zitat:

Zitat von softtouch (Beitrag 1504997)
Ich suche eine RandomRange Funktion die mit int64 anstatt integer arbeitet.
Habe leider bisher nichts gefunden.
Ich muss eine Zufallszahl zwischen 100000 und 9999999999 erzeugen.

Erzeuge eine GUID (System.SysUtils.CreateGUID) und säge 64 bits von den 128 ab, dann hast Du eine 64-bit random uint. Die mußt Du dann nur noch auf den gewünschten Range justieren :wink:

himitsu 23. Apr 2022 18:00

AW: Delphi 11 kein RandomRange für 64-bits?
 
Wird auch nicht ganz klappen, auf Grund der Structur von GUIDs.

Das Result nahezu immer im oberen Bereich liegen also bei 9999999999 fast immer im Bereich von 0200000000 bis 9999999999,
was dann gegen eine Normalverteilung von Zufallszahlen spricht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:51 Uhr.
Seite 1 von 3  1 23      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz