AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Delphi 11 kein RandomRange für 64-bits?

Ein Thema von softtouch · begonnen am 23. Apr 2022 · letzter Beitrag vom 11. Aug 2022
Antwort Antwort
Seite 1 von 3  1 23      
Benutzerbild von softtouch
softtouch

Registriert seit: 13. Feb 2015
Ort: Kerpen
235 Beiträge
 
Delphi 12 Athens
 
#1

Delphi 11 kein RandomRange für 64-bits?

  Alt 23. Apr 2022, 09:28
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.
  Mit Zitat antworten Zitat
Andreas13

Registriert seit: 14. Okt 2006
Ort: Nürnberg
719 Beiträge
 
Delphi XE5 Professional
 
#2

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

  Alt 23. Apr 2022, 10:03
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.
Grüße, Andreas
Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher. (John C. Cornelius)

Geändert von Andreas13 (23. Apr 2022 um 10:07 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von softtouch
softtouch

Registriert seit: 13. Feb 2015
Ort: Kerpen
235 Beiträge
 
Delphi 12 Athens
 
#3

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

  Alt 23. Apr 2022, 10:14
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.
  Mit Zitat antworten Zitat
Andreas13

Registriert seit: 14. Okt 2006
Ort: Nürnberg
719 Beiträge
 
Delphi XE5 Professional
 
#4

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

  Alt 23. Apr 2022, 10:19
Sorry, in der Tat. Ich habe es leider nur in der Nähe Deines oberen Breichs
Delphi-Quellcode:
Von:= 9999999999 - 500;
Bis:= 9999999999;
getestet.

Andreas
Grüße, Andreas
Wenn man seinem Nächsten einen steilen Berg hinaufhilft, kommt man selbst dem Gipfel näher. (John C. Cornelius)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#5

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

  Alt 23. Apr 2022, 10:41
Vielleicht klappt dies besser:
Delphi-Quellcode:
Function RandomRange(Const AFrom, ATo: UInt64): UInt64;
Begin
  Result:= Round(Random*(ATo - AFrom)) + AFrom;
End;
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von KodeZwerg
KodeZwerg

Registriert seit: 1. Feb 2018
3.691 Beiträge
 
Delphi 11 Alexandria
 
#6

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

  Alt 23. Apr 2022, 10:57
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.
Gruß vom KodeZwerg
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#7

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

  Alt 23. Apr 2022, 11:01
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.
$2B or not $2B

Geändert von himitsu (23. Apr 2022 um 11:04 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.475 Beiträge
 
Delphi 12 Athens
 
#8

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

  Alt 23. Apr 2022, 11:42
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.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
peterbelow

Registriert seit: 12. Jan 2019
Ort: Hessen
704 Beiträge
 
Delphi 12 Athens
 
#9

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

  Alt 23. Apr 2022, 17:27
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
Peter Below
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#10

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

  Alt 23. Apr 2022, 19:00
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.
$2B or not $2B
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:07 Uhr.
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