![]() |
Random: Delphi vs. Lazarus?
Kennt jemand die Unterschiede?
Folgendes habe ich zu der Funktion bei Lazarus gefunden: Zitat:
|
AW: Random: Delphi vs. Lazarus?
DELPHI2009
![]() // Quellcode entfernt - seid bitte so gut und veröffentlicht keinen Quellcode aus dem Produkt. Die Sourcen liegen nicht jeder Edition bei und daher dürfen wir sie hier auch nicht - nicht einmal auszugsweise - veröffentlichen. Sorry, ist aber so und ich möchte mich da auch Problemen heraushalten - ich bitte um Verständnis. Daniel |
AW: Random: Delphi vs. Lazarus?
Der in Delphi und Pascal ist seit langem der gleiche, ein linearer
![]()
Delphi-Quellcode:
mit a = $08088405 = 134775813
x[n+1] = a*x[n] + 1 mod 2^32;
Edit: der gleiche heißt hier, daß er sich seit TurboPascal 5/6/7 nicht geändert hat, nicht das er der gleiche wie in neueren FPC-Versionen ist. |
AW: Random: Delphi vs. Lazarus?
Ein Random-Generator?
Ist standardmässig eine mehr oder weniger komplizierte Formel, welche bestimmten Anforderungen genügen muss. Hauptsache bei einer solchen Formel ist, dass sie sich auch nicht im millionsten Durchlauf in eine Ecke drängt, und statistisch gesehen, laufend den ganzen Wertebereich möglichst gleichmässig abdeckt. Wenn nun Lazarus und Delphi die gleiche Implementation verwenden, wen stört es? Ich will ja (Pseudo-)Zufallszahlen bekommen, und nicht einen fremden Schlüssel knacken. Nur schon, wenn ich eine bestimmte Startzahl eingebe, kommt eine gaaaaanz andere Reihenfolge heraus. PC-John |
AW: Random: Delphi vs. Lazarus?
Um es nochmal zusammenzufassen: Delphi verwendet einen linearen Kongruenzgenerator während FreePascal einen Mersenne Twister benutzt.
Das heißt, dass Delphi einen sehr schnellen, aber für viele ernsthafte Anwendungen von Zufallzahlen unbrauchbaren, Generator hat. Dafür ist der Generator von FreePascal langsamer. Auf Wikipedia gibt es auch eine schöne ![]() |
AW: Random: Delphi vs. Lazarus?
Für ernsthafte Anwendung kann man ja notfalls auch einen den vielen alternativen Zufallsgeneratoren verwenden.
Im DEC war auch einer drin und wenn es ganz sicher sein muß, dann gäbe es auch spezielle hardwarebasierte Systeme. |
AW: Random: Delphi vs. Lazarus?
Habe ich richtig verstanden?
Delphi - linearer Kongruenzgeneratoren - 2^32 = schnell, aber nicht sehr sicher. Lazarus - Mersenne-Twister Pseudozufallszahlengenerator - (2^19937)−1 = langsam, aber dafür viel sicherer? Also doch sehr unterschiedlich. |
AW: Random: Delphi vs. Lazarus?
Zitat:
Der Unterschied ist aber trotzdem wichtig, z.B. wenn man randomisierte Algorithmen einsetzen will (Monte-Carlo-Simulation, usw.). Wenn du Spaß mit Verschlüsselung haben willst, programmiere lieber einen Standard nach :mrgreen: |
AW: Random: Delphi vs. Lazarus?
Als Alternative zu Random kannst du auch die GUID von Windows verwenden. Nach meinen Erfahrungen sind die resultierenden Zufallswerte recht gut und liefern auch eine brauchbare Statistik. Hier ein Beispiel:
Code:
// get random number via GUID
function random_GUID(n : integer) : integer; var Guid : TGUID; num : integer; begin CreateGUID(Guid); num := Trunc(1 + (n*(Guid.D2/65535))); if num = 0 then num := 1; if num = n+1 then num := n; Result := num; end; |
AW: Random: Delphi vs. Lazarus?
Ist ja abenteuerlich...
|
AW: Random: Delphi vs. Lazarus?
Zwar abenteuerlich, aber liefert wenigstens halbwegs zufallsaehnliche Zahlen waehrend Random mit Randomize immer identische Abfolgen generiert...
|
AW: Random: Delphi vs. Lazarus?
Bist du sicher, dass du Randomize auch nur einmalig aufgerufen hast? Ich hatte solche Probleme nur, wenn ich es versehentlich mehrfach aufgerufen hatte oder ganz vergessen hatte.
Deine Implementierung hat dagegen einige Probleme: Das erste if ist meiner Meinung nach komplett sinnlos, da num nach der vorherigen Zeile nie kleiner als 1 sein kann – da stellt man sich beim Lesen erst mal die Frage, ob Autor des Codes überhaupt weiß, was er tut – das sorgt nicht gerade für Vertrauen. Und das Zweite if ist noch schlimmer, denn es sorgt dafür, dass n statistisch häufiger vorkommt als alle anderen Werte. |
AW: Random: Delphi vs. Lazarus?
Dann doch lieber selber einen der besseren Generator implementieren oder die Windows CryptAPI benutzen.
Du hast afaik keine Garantien, das die GUID in Zukunft (spätere Windowsversionen) auch noch "zufällig" genug ist. Aber interessante Idee :mrgreen: |
AW: Random: Delphi vs. Lazarus?
Zitat:
|
AW: Random: Delphi vs. Lazarus?
Dass das erste if keinen Sinn macht gebe ich dir Recht. Ist ein Relikt einer vorherigen Implementation in der das 1+ nicht im Trunc war. Aendert aber nichts an der Funktionalitaet.
Bezueglich des zweiten ifs: Auch dieser Einwand ist richtig. Allerdings ist der Einfluss sehr gering und die resultierenden statitischen Verteilungen sind vielfach besser als bei Random. Wenn jemand eine Idee hat wie man die Randbedingung ohne Grossen Aufwand besser loest waere ich dankbar. Randomize hatte ich nur einmal vorher aufgerufen. Sehe aber auch keinen Grund warum man es nicht oefter aufrufen duerfte. Nach meinem Verstaendnis setzt Randomize nur einen beliebigen Startpunkt fest von dem aus die weiteren Werte mit Random bestimmt werden. Da der Startpunkt zufaellig ist sollte man Randomize doch auch beliebig aufrufen duerfen, oder nicht? |
AW: Random: Delphi vs. Lazarus?
Der Startpunkt ist nicht zufällig – wie auch. Man braucht ja gerade den Zufallsgenerator, um „zufällige“ Werte zu erzeugen. Wie soll man dann einen echt zufälligen Startpunkt für den Zufallsgenerator finden? Ein Computer ist nun mal deterministisch.
Randomize setzt den Startpunkt auf die aktuelle Uptime. Wenn man das in kurzen Abständen hintereinander ausführt, kommen da immer der gleiche oder sehr ähnliche Seeds bei heraus, und dadurch ergeben sich auch immer gleiche oder ähnliche Zahlenfolgen. |
AW: Random: Delphi vs. Lazarus?
Zitat:
|
AW: Random: Delphi vs. Lazarus?
Zitat:
|
AW: Random: Delphi vs. Lazarus?
Zitat:
|
AW: Random: Delphi vs. Lazarus?
Noch mal zum Thema Geschwindigkeit vs. Sicherheit bzw Periodenlänge: So einfach wie hier zusammengefaßt
Zitat:
![]() |
AW: Random: Delphi vs. Lazarus?
Aber wie sieht es mit der Sicherheit der Passwörter aus? Die von Delphi sind schneller zu knacken wie ich verstehe.
Gib's eigentlich einen Cross-Platform-Zufallsgenerator, der NSA oder "Wasser und Bombenfest" ist? |
AW: Random: Delphi vs. Lazarus?
Zitat:
|
AW: Random: Delphi vs. Lazarus?
Zitat:
![]() Es gibt wohl sichere Generatoren (zB ![]() |
AW: Random: Delphi vs. Lazarus?
Zitat:
Es sei denn du hattes den Fehler der Fehler gemacht und Randomize zu häufig aufgerufen. |
AW: Random: Delphi vs. Lazarus?
Zitat:
Denn an sich wüsste ich nicht, wieso das normale Delphi-Random sonst „schlechte“ Zufallsfolgen ausspucken sollte. Der RNG taugt vielleicht nicht für kryptografische Zwecke, aber bemerkbare Regelmäßigkeiten treten da eigentlich nicht auf (anders als z.B. beim Standard-random von PHP). |
AW: Random: Delphi vs. Lazarus?
Dazu gabs eine längere Diskussion auf der FPC Mailinglist
![]() |
AW: Random: Delphi vs. Lazarus?
Zitat:
Also Randomize NICHT zu oft aufrufen, dann kann so etwas passieren.:warn: |
AW: Random: Delphi vs. Lazarus?
Zitat:
|
AW: Random: Delphi vs. Lazarus?
Früher ging Randomize mal auf GetTickCount, welches meistens in einem Intervall von 16 Millisekunden hochzählte. (glaub ich)
Aber da Zuviele zuviele Fehler machenten, wurde es umgebaut. Inzwischen wird wohl QueryPerformanceCounter verwendet, damit sich solche Fehler nicht all zu sehr auswirken. Und für die, welche Randomize vergessen aufzurufen, macht das jetzt die VCL einmal, beim Start. Man könnte zwar Randomize oder den Seed öfters aufrufen/setzen, aber der Zufallsgenerator hat irgendwie soeine durchschnittliche "Gleichverteilung" und diese Verteilung der Zufallswerte könnte man damit negativ beeinflussen. Also, im Normalfall kommen alle Zufallszahlen, über einen ausreichend großen Bereich hinweg, ungefähr gleich oft vor. Ein "Vorteil" am Delphi-Random ist, daß man, ausgehend von einem bestimmten Seed, immer die selben Zahlen bekommt. (solange keiner die zugrundeliegende Berechnung verändert) |
AW: Random: Delphi vs. Lazarus?
Zitat:
|
AW: Random: Delphi vs. Lazarus?
Namenloser,
wenn du moechtest kannst du mal folgendes ausprobieren: 1) Lasse dir ein paar Millionen Lottotips generieren fuer Lotto 6 aus 49 2) Danach erstelle eine Statistik fuer die Zahlen 1 bis 49 an welcher Stelle die Zahl in jedem Tipp vorkommt. Plotte die resultierenden sechs Hauefigkeitskurven (erste Stelle, zweite Stelle, ...) ueber die Zahlen 1 bis 49. Wenn du das einmal mit Delphi random machst und einmal mit einem besseren Generator machst wirst du sehen dass die Delphi random Werte schlecht sind und die Statistik stark verzerren. |
AW: Random: Delphi vs. Lazarus?
Zitat:
![]() Zitat:
Gruß, Sven |
AW: Random: Delphi vs. Lazarus?
Zitat:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var c0,c,c1 : Cardinal; begin c := GetTickCount; c0 := c; repeat c1 := GetTickCount; if c<>c1 then begin memo1.lines.add(intToStr(c-c0)); c := c1; End; until c1-c0>100; end; Zitat:
|
AW: Random: Delphi vs. Lazarus?
"The resolution of the GetTickCount function is limited to the resolution of the system timer, which is typically in the range of 10 milliseconds to 16 milliseconds."
![]() |
AW: Random: Delphi vs. Lazarus?
Zitat:
weisst du wie die Funktion random(pWert:integer):integer arbeitet? Ist das einfach:
Delphi-Quellcode:
Gruß
random:=zufallszahl mod pWert;
|
AW: Random: Delphi vs. Lazarus?
Nee
Delphi-Quellcode:
Es ist im Prinzip eher etwas wie
function Random(const ARange: Integer): Integer;
{$IFDEF PUREPASCAL} var Temp: Longint; begin Temp := RandSeed * $08088405 + 1; // berechne den nächsten Wert RandSeed := Temp; // Result := (UInt64(Cardinal(ARange)) * UInt64(Cardinal(Temp))) shr 32; end;
Delphi-Quellcode:
Result := Random * pWert; // Random liefert ja 0 bis 0.999999 (oder war es 0 bis 1?)
|
AW: Random: Delphi vs. Lazarus?
Hi Himitsu.
Zwei Dinge verstehe ich nicht.
|
AW: Random: Delphi vs. Lazarus?
Zitat:
Zitat:
Satty67 hat sich ![]() |
AW: Random: Delphi vs. Lazarus?
Zitat:
Delphi-Quellcode:
function Random: Extended;
const two2neg32: double = ((1.0/$10000) / $10000); // 2^-32 {$IFDEF PUREPASCAL} var Temp: LongInt; F: Extended; begin Temp := RandSeed * $08088405 + 1; RandSeed := Temp; F := Temp; Result := F * two2neg32; end; |
AW: Random: Delphi vs. Lazarus?
Zitat:
Delphi-Quellcode:
verwendete Interval [0,1) kann man
random
Delphi-Quellcode:
benutzen, und eine ähnliche Formel wenn man mehr als 32 Bit braucht.
//...
Result := (Temp + 2147483648.0) / 4294967296.0; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:41 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz