Delphi-PRAXiS
Seite 14 von 14   « Erste     4121314   

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Random ist kein reiner Zufall (https://www.delphipraxis.net/89462-random-ist-kein-reiner-zufall.html)

Cöster 4. Apr 2007 16:51

Re: Random ist kein reiner Zufall
 
Zitat:

Zitat von dino
obwohl Random bei mir wesentlich kleiner ausfällt

Das liegt wohl daran, dass der Teil zwischen {$IFDEF PIC} und {ELSE} wegfällt.

Zitat:

Zitat von dino
ich bin nun auf der Suche nach result

:wiejetzt: Also das Result der Funktion ist das, was am Ende in EAX steht. Oder was meinst du?

dino 4. Apr 2007 17:15

Re: Random ist kein reiner Zufall
 
ja eigentlich meine ich das, aber da kommt bei mir immer 0 raus

Cöster 4. Apr 2007 21:09

Re: Random ist kein reiner Zufall
 
Also zunächst mal: Bei MUL EDX wird ja EAX mit EDX multipliziert. Das Ergebnis einer Multiplikation zweier 32Bit-Zahlen kann allerdings bis zu 64Bit beanspruchen. Deswegen wird das Ergebnis ins Registerpaar EDX:EAX geschrieben. Die 32 höherwertigen Bits stehen dabei in EDX.

Ursache dafür, dass das Result bei dir 0 ist, könnte sein:
Der Parameter ist 1 :lol:, es ist Zufall (:wink:) oder du rufst Randomize nicht auf. Denn wenn Randomize nirgendwo im Programm aufgerufen wird, ist RandSeed ja beim ersten Random-Aufruf 0. Nach folgenden 3 Zeilen ist RandSeed dann 1:

Code:
imul edx,[RandSeed],$0808804 // EDX := RandSeed(=0)*Konstante => EDX=0
inc edx                     // => EDX=1
mov [RandSeed],edx          // => RandSeed = 1
Dann wird EDX (=1) mit EAX (=Parameter, Größe: 32Bit) multipliziert. Das Ergebnis ist also EAX. Da die 32 niedrigwertigen Bits des Ergebnisses in EAX geschrieben werden, bleibt EAX unverändert (=Parameter) und EDX wird genullt.

Am Ende wird EDX (=0) dann in EAX kopiert und zurückgegeben. Deswegen ist die erste erzeugte Zufallszahl immer null, wenn Randomize nicht aufgerufen wurde.

dino 4. Apr 2007 22:08

Re: Random ist kein reiner Zufall
 
gehts auch mit Randomize?

schliesslich muss Random(3) ja seinen wert haben

Cöster 5. Apr 2007 14:38

Re: Random ist kein reiner Zufall
 
Zitat:

Zitat von dino
gehts auch mit Randomize?

schliesslich muss Random(3) ja seinen wert haben

Ich versteh nicht was du meinst. Was geht auch mit Randomize? Was ist "sein Wert"?

QuickAndDirty 5. Apr 2007 15:06

Re: Random ist kein reiner Zufall
 
Nachfolgend mal ein Beitrag aus google Groups
Das sollte dann wohl alle fragen beantworten.
Zitat:

Die einfachste und fuer sehr viele Zwecke ausreichende Methode ist die
sogenannte lineare Kongruenzmethode, die sich auf Rechnern leicht und schnell
implementieren laesst. Wir nehmen an, dass der Rechner z.b. mit Zahlen zwischen
0 und 2^32-1 rechnen kann.

Dann liefert die Formel

Seed_neu = (08088485h * Seed_alt + 1) mod 2^32

in Turbo-Pascal

var RandSeed:longint;

RandSeed := $08088405*RandSeed + 1;

eine Zahlenfolge, in denen saemtliche Werte zwischen 0 und 2^32-1 genau einmal
vorkommen und die sich dann wiederholt. Die Operation liefert also eine
Reihenfolge/Aufzaehlung/Permutation aller Zahlen 0..2^32-1. Diese Permutation
ist nachweislich recht "zufaellig". Um nachzuweisen, dass die Formel

Seed_neu = (c*Seed_alt + 1) mod 3^32

tatsaechlich alle Zahlen von 0..2^32-1 aufzaehlt und keine "vergisst", ist
nicht ganz einfach. Vor allem ist die Wahl von c nicht trivial. Man kann
zeigen, dass die Zahl c kongruent 5 modulo 8 sein muss, damit die obige Formel
fuer eine beliebige (!) 2-er-Potenz als Modul eine vollstaendige Permutation
0..Modul-1 liefert. c darf nicht zu gross und nicht zu klein sein, damit die
Folge dann "zufaellig" aussieht. Der obige Wert von c ist gut und wird z.b. von
der Funktion Random in Turbo-Pascal verwendet.

Die obige Folge liefert aber noch lange nicht das, was man unter einer
Zufallsfolge versteht, also z.B. unter einer zufaelligen Gleichverteilung der
Zahlen {0,1} oder allgemein {0,1,...,n-1}, denn sie ist zunaechst nur eine
Permutation, in der sich Werte nur nach 4 Milliarden Zuegen wiederholen. Dazu
muss man sie noch einer geeigneten Transformation unterwerfen, damit man nur
Werte aus {0..n-1} erhaelt, die sich dann natuerlich auch in kuerzeren
Abstaenden wiederholen sollen/muessen.

Dazu muessen hier die _hohen_ Bits von Seed "abgegriffen" werden.

Die Operation "Seed mod n" waere denkbar ungeeignet, denn sie liefert z.b. fuer
n=2 offensichtlich fuer aufeinanderfolgende Seed-Werte abwechselnd 0 und 1.

Die korrekte Transformation lautet hier

Seed := (c*Seed+1) mod 2^32
Random := (n*Seed) div 2^32 { Wert aus {0,...,n-1}

Sie sollte nur fuer maximal n=2^16 angewandt werden. D.h. fuer einen
"richtigen" Zufallszahlengenerator fuer 16-Bit-Werte braucht man einen
Zufallspermutationsgenerator von mindestens 32 Bit Laenge.

Dieser Algorithmus hat den Vorzug, dass er wahrscheinlich der
schnellstmoegliche sinnvolle Pseudeo-Zufalls-Algorithmus ist und er ist in den
meisten Compiler implementiert, die eine Zufallsfunktion bereitstellen (Basic,
Pascal,Fortran,C).

Um den Gererator bei Programmstart zu _initialisieren_ gibt es meist eine
Funktion namens Randomize, die ueblicherweise die Systemzeit ausliest und Seed
damit auf einen halbwegs nicht reproduzierberen und unerwarteten Wert setzt.
Wenn man die Zufallsfolge reproduzierbar sein soll, kann man Seed von Hand auf
einen beliebigen Wert setzen, den man sich merkt. Dann wird immer dieselbe
"Zufallsfolge" erzeugt. die Initialisierung sollte aber nur einmal geschehen,
da wiederholtes Randomize die Folge eher verschelchtert als verbessert.

Fuer sehr hohe Ansprueche gibt es erheblich kompliziertere und auch bessere
Pseudo-Zufallsgeneratoren.

cu
Horst
Da wo er einmal von "mod 3 " spricht ist wohl mod 2 gemeint.
hier die Quelle
http://groups.google.de/group/fido.g...81eb097e3b72d4

Noch etwas in Delphi kann auf mod 2^32 verzichtet werden da Variablen einfach überlaufen.

dino 5. Apr 2007 17:35

Re: Random ist kein reiner Zufall
 
der spricht da nirgendswo von mod 3 (oder meinst du mod3^32?)

dino 6. Apr 2007 23:24

Re: Random ist kein reiner Zufall
 
naja jedenfalls habe ich mit sachen wie Random := (n*Seed) div 2^32 { Wert aus {0,...,n-1} herrumgespielt doch habs immernoch nicht raus(wie gesagt: den neuen randseed kriege ich schon nur result nicht)


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:15 Uhr.
Seite 14 von 14   « Erste     4121314   

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