Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Zufallszahl ermiteln (https://www.delphipraxis.net/22395-zufallszahl-ermiteln.html)

Christian18 17. Mai 2004 10:45


Zufallszahl ermiteln
 
hallo,

ich möchte gerne mir Delphi eine Zufallszahl ermitteln. Die zahl soll zwischen 0 und 100 liegen. Wie mache ich das.

Mit freundlichen Grüßen

Christian18

sakura 17. Mai 2004 10:48

Re: Zufallszahl ermiteln
 
Die Lösung heißt Hier im Forum suchenRandom und Hier im Forum suchenRandomize

...:cat:...

Christian18 17. Mai 2004 14:14

Re: Zufallszahl ermiteln
 
hallo,

ok es funktioniert jetzt erst einmal, aber wenn ich das programm starte, dann kommen werte z.b. 1, 73, 254, 84.

und wenn ich das programm das nächte mal starte, dann kommen genau die gleichen werte. dann ist das doch kein zufallswert oder??? wie kann ich das beheben???

mirage228 17. Mai 2004 14:16

Re: Zufallszahl ermiteln
 
Du musst

Randomize vor Random() aufrufen.

Dann sollten die Werte zufällig sein.

mfG
mirage228

sakura 17. Mai 2004 14:16

Re: Zufallszahl ermiteln
 
Ich zitiere nochmals ;)

Zitat:

Zitat von sakura

Letzteres ist zu diesem Problem die Lösung ;)

...:cat:...

sakura 17. Mai 2004 14:17

Re: Zufallszahl ermiteln
 
Zitat:

Zitat von mirage228
Randomize vor Random() aufrufen.

Ein wichtiger Teil fehlt :shock: Hier im Forum suchenRandomize nur einmal pro Programmstart aufrufen :!:

...:cat:...

gekmihesg 17. Mai 2004 14:17

Re: Zufallszahl ermiteln
 
hast du die funktion randomize verwendet?
wahrscheinlich nicht, weil die dazu gedacht is genau das zu verhindern!
schreib am besten in des onCreate ereigniss deines forms einfach randomize; dann sollts gehn

mirage228 17. Mai 2004 14:24

Re: Zufallszahl ermiteln
 
Zitat:

Zitat von sakura
Zitat:

Zitat von mirage228
Randomize vor Random() aufrufen.

Ein wichtiger Teil fehlt :shock: Hier im Forum suchenRandomize nur einmal pro Programmstart aufrufen :!:

...:cat:...

Das stimmt allerdings... habe ich vergessen zu schreiben :wall:

mfG
mirage228

Ultimator 17. Mai 2004 16:11

Re: Zufallszahl ermiteln
 
Zitat:

Zitat von sakura
Ein wichtiger Teil fehlt :shock: Hier im Forum suchenRANDOMIZE nur einmal pro Programmstart aufrufen :!:

Es ist zwar besser wenn man es nur einmal aufruft, aber es ist nicht soo Hammer-schlimm, wenn man es öfters macht.

sakura 17. Mai 2004 16:15

Re: Zufallszahl ermiteln
 
Zitat:

Zitat von Ultimator
Es ist zwar besser wenn man es nur einmal aufruft, aber es ist nicht soo Hammer-schlimm, wenn man es öfters macht.

Sicher ;) Es geht a) auf die Performance und b) mindert es die Qualität der Zufallszahlen.

In älteren Delphi Versionen, auf Linux und auf älteren Windows Versionen kannst Du mit folgendem Konstrukt schnell mal 1000 gleiche Zahlen erreichen.

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
begin
  Memo1.Lines.BeginUpdate;
  try
    for I := 0 to 999 do
    begin
      Randomize;
      Memo1.Lines.Add(IntToStr(Random(MaxInt)));
    end;
  finally
    Memo1.Lines.EndUpdate;
  end;
end;
Deswegen, Randomize nur einmal aufrufen.

...:cat:...

Nicodius 17. Mai 2004 16:18

Re: Zufallszahl ermiteln
 
FormCreate--> ranodmize;

Aktionsaufruf-->random(maxwert)

eroe 17. Mai 2004 17:17

Re: Zufallszahl ermiteln
 
Zitat:

Zitat von sakura
Zitat:

Zitat von Ultimator
Es ist zwar besser wenn man es nur einmal aufruft, aber es ist nicht soo Hammer-schlimm, wenn man es öfters macht.

Sicher ;) Es geht a) auf die Performance und b) mindert es die Qualität der Zufallszahlen.

In älteren Delphi Versionen, auf Linux und auf älteren Windows Versionen kannst Du mit folgendem Konstrukt schnell mal 1000 gleiche Zahlen erreichen.

Delphi-Quellcode:
(code)
Deswegen, Randomize nur einmal aufrufen.

...:cat:...

ehrlich ? nach welchem schema werden die "pseudo"-zufallszahlen denn in delphi erstellt ? ich mein wenn das stimmt was du sagst, dann können sie doch gar nich 100% zufällig sein oder ?

PS: soll keine anzweiflung deiner these sein, mich wunderts nur ein wenig ;)

Sharky 17. Mai 2004 17:21

Re: Zufallszahl ermiteln
 
Zitat:

Zitat von eroe
....ehrlich ? nach welchem schema werden die "pseudo"-zufallszahlen denn in delphi erstellt ? ich mein wenn das stimmt was du sagst, dann können sie doch gar nich 100% zufällig sein oder ?....

Ein wichtiger Aspekt bei der Initialisierung durch Randomize ist die Systemzeit. Und bei den heutigen Systemen ist eine Schleife von 0 bis 999 halt schneller durchlaufen als sich der relevante Teil der Zeit ändert. Darum sollte Randomize nur einmal (beim Start des Programmes) aufgerufen werden. Sonst wird das "Zufallssystem" immer wieder auf den selben Startwert gesetzt.

Und JA: ECHTE Zufallszahlen werden mit Delphi (kann das über haupt ein normaler PC?) nicht erzeugt.

sakura 17. Mai 2004 17:24

Re: Zufallszahl ermiteln
 
Zitat:

Zitat von eroe
ehrlich ? nach welchem schema werden die "pseudo"-zufallszahlen denn in delphi erstellt ? ich mein wenn das stimmt was du sagst, dann können sie doch gar nich 100% zufällig sein oder ?

Wie der Name "Pseudo-" schon sagt, sind diese nicht echt. Delphi berechnet diese. Der relavante Teil ist in Delphi 7 wie folgend (ändert sich von Version zu Version)
Delphi-Quellcode:
procedure      _RandInt;
asm
{     ->EAX    Range  }
{     <-EAX    Result }
        PUSH   EBX
{$IFDEF PIC}
        PUSH   EAX
        CALL   GetGOT
        MOV    EBX,EAX
        POP    EAX
        MOV    ECX,[EBX].OFFSET RandSeed
        IMUL   EDX,[ECX],08088405H
        INC    EDX
        MOV    [ECX],EDX
{$ELSE}
        XOR    EBX, EBX
        IMUL   EDX,[EBX].RandSeed,08088405H
        INC    EDX
        MOV    [EBX].RandSeed,EDX
{$ENDIF}
        MUL    EDX
        MOV    EAX,EDX
        POP    EBX
end;

procedure      _RandExt;
const two2neg32: double = ((1.0/$10000) / $10000); // 2^-32
asm
{       FUNCTION _RandExt: Extended;   }

        PUSH   EBX
{$IFDEF PIC}
        CALL   GetGOT
        MOV    EBX,EAX
        MOV    ECX,[EBX].OFFSET RandSeed
        IMUL   EDX,[ECX],08088405H
        INC    EDX
        MOV    [ECX],EDX
{$ELSE}
        XOR    EBX, EBX
        IMUL   EDX,[EBX].RandSeed,08088405H
        INC    EDX
        MOV    [EBX].RandSeed,EDX
{$ENDIF}

        FLD    [EBX].two2neg32
        PUSH   0
        PUSH   EDX
        FILD   qword ptr [ESP]
        ADD    ESP,8
        FMULP  ST(1), ST(0)
        POP    EBX
end;
...:cat:...

sakura 17. Mai 2004 17:25

Re: Zufallszahl ermiteln
 
Zitat:

Zitat von Sharky
Ein wichtiger Aspekt bei der Initialisierung durch Randomize ist die Systemzeit.

Nicht unbedingt, in Delphi 7 wird der Performance-Counter genutzt, und der ist schnell genug ;)

Delphi-Quellcode:
procedure      Randomize;
{$IFDEF LINUX}
begin
  RandSeed := _time(nil);
end;
{$ENDIF}
{$IFDEF MSWINDOWS}
var
  Counter: Int64;
begin
  if QueryPerformanceCounter(Counter) then
    RandSeed := Counter
  else
    RandSeed := GetTickCount;
end;
{$ENDIF}
...:cat:...

eroe 17. Mai 2004 17:27

Re: Zufallszahl ermiteln
 
Delphi-Quellcode:
procedure      _RandInt;
asm
{     ->EAX    Range  }
{     <-EAX    Result }
        PUSH   EBX
{$IFDEF PIC}
        PUSH   EAX
        CALL   GetGOT
        MOV    EBX,EAX
        POP    EAX
        MOV    ECX,[EBX].OFFSET RandSeed
        IMUL   EDX,[ECX],08088405H
        INC    EDX
        MOV    [ECX],EDX
{$ELSE}
        XOR    EBX, EBX
        IMUL   EDX,[EBX].RandSeed,08088405H
        INC    EDX
        MOV    [EBX].RandSeed,EDX
{$ENDIF}
        MUL    EDX
        MOV    EAX,EDX
        POP    EBX
end;

procedure      _RandExt;
const two2neg32: double = ((1.0/$10000) / $10000); // 2^-32
asm
{       FUNCTION _RandExt: Extended;   }

        PUSH   EBX
{$IFDEF PIC}
        CALL   GetGOT
        MOV    EBX,EAX
        MOV    ECX,[EBX].OFFSET RandSeed
        IMUL   EDX,[ECX],08088405H
        INC    EDX
        MOV    [ECX],EDX
{$ELSE}
        XOR    EBX, EBX
        IMUL   EDX,[EBX].RandSeed,08088405H
        INC    EDX
        MOV    [EBX].RandSeed,EDX
{$ENDIF}

        FLD    [EBX].two2neg32
        PUSH   0
        PUSH   EDX
        FILD   qword ptr [ESP]
        ADD    ESP,8
        FMULP  ST(1), ST(0)
        POP    EBX
end;

ACH KLAR !! jetz wo dus sagst ;) :D
aber danke schonmal für die erläuterung, hätt ich nich gedacht ..

@ Sharky .. naja, das sie nich 100 % zufall sind war relativ klar, aber ich hätt nich erwartet das sie von so nem unsicheren faktor wie systemzeit abhängen, zumindest nimmer heutzutage ..

ajz 18. Mai 2004 07:30

Re: Zufallszahl ermiteln
 
Zitat:

Zitat von Sharky
Zitat:

Zitat von eroe
....ehrlich ? nach welchem schema werden die "pseudo"-zufallszahlen denn in delphi erstellt ? ich mein wenn das stimmt was du sagst, dann können sie doch gar nich 100% zufällig sein oder ?....

Ein wichtiger Aspekt bei der Initialisierung durch Randomize ist die Systemzeit. Und bei den heutigen Systemen ist eine Schleife von 0 bis 999 halt schneller durchlaufen als sich der relevante Teil der Zeit ändert. Darum sollte Randomize nur einmal (beim Start des Programmes) aufgerufen werden. Sonst wird das "Zufallssystem" immer wieder auf den selben Startwert gesetzt.

Und JA: ECHTE Zufallszahlen werden mit Delphi (kann das über haupt ein normaler PC?) nicht erzeugt.

ein normaler pc kann das nicht,
aber ein normaler pc, der in irgendeiner weise mit einer stereoanlage oder einer soundkarte verbunden ist,
mit dem kann man echte zufallszahlen aus dem rauschen der (sound-) chips machen/berechnen.

Line out mit Line in verbinden, rauschen der eigenen soundkarte oder stereoanlage aufnehmen und
die frequenzen des rauschens als grundlage für die berechnung einer zufallszahl nehmen.
d.h. würde das randomize() von delphi nicht mit der systemzeit
sondern mit irgendeinem rauschen von einem soundchip initialisiert, wären die zufallszahlen um einiges
zufälliger...

mfg

negaH 18. Mai 2004 07:40

Re: Zufallszahl ermiteln
 
Zitat:

ch mein wenn das stimmt was du sagst, dann können sie doch gar nich 100% zufällig sein oder ?
Korrekt, es sind Pseudo-Zufalls-Zahlen, und die sind 100% nicht zufällig, haben aber meistens zu 100% die Statistischen Eigenschaften von Zufall. Umschrieben heist das, die Farbe ist Blau aber eben kein echtes Blau, hat aber die exakt gleichen Eigenschaften wie das echte Blau (eben bläulich). Wenn man also nicht weis das das Pseudo-Blau kein echtes Blau ist dann wird es sehr schwierig das Pseudo-Blau vom echten Blau zu unterscheiden ;) Der Vorteil ist aber das mit dem gleichen Mischungsverhältnis der Zutaten eben immer exakt das gleiche Pseudo-Blau erzeugt werden kann. In unserem Falle ist es gerade eine perfekte und vorzügliche Eigenschaft von Random() das sie mit dem gleichen Zufalls-Seed immer den gleichen Pseudo-Zufall erzeugt. Erst dadurch wird es möglich immer wiederkehrend zufällige Ereignisse zu reproduzieren. Bei echtem Zufall geht dies eben nicht.

Gruß Hagen

negaH 18. Mai 2004 07:45

Re: Zufallszahl ermiteln
 
Übrigens, warte mal Donnerstag ab, dem Männertag, dann kennst du den Unterschied zwischen Blau und Pseudo-Blau :cheers: ;)

Gruß Hagen

p0w3r5tr34m3r 18. Mai 2004 13:39

Re: Zufallszahl ermiteln
 
kannst auch einfach die unit MATH einbinden und dann randomrange(0,100) machen :)

so long,
Powerstreamer

Nicolai1234 18. Mai 2004 14:10

Re: Zufallszahl ermiteln
 
was macht diese function anders?

p0w3r5tr34m3r 18. Mai 2004 15:34

Re: Zufallszahl ermiteln
 
gar nix.. si aber auch ne möglichkeit ne zufällige zahl herauszugeben...

eroe 18. Mai 2004 22:14

Re: Zufallszahl ermiteln
 
Zitat:

Zitat von negaH
Übrigens, warte mal Donnerstag ab, dem Männertag, dann kennst du den Unterschied zwischen Blau und Pseudo-Blau :cheers: ;)

Gruß Hagen

LOL :D nich verkehrt, echt nich verkehrt ;)
btw deine definition eines unzufälligen zufallswertes hat mich schwer beeindruckt, wenn nich gar inspiriert :D
das werd ich ma meinem info lehrer vortragen und mir n paar plus-pünktchen abholen ;)
afaik hat hier irgendjemand gesagt, das dieser fall der gleichen zufallszahlen nur in d6 und früher (oder so) eintreten kann .. was ist denn ab d6 der faktor für die berechnung von zufallszahlen, wenn nicht mehr systemzeit ?

negaH 19. Mai 2004 17:01

Re: Zufallszahl ermiteln
 
Hm, das kann ich garnicht glauben, und muss es selber erstmal testen.
Allgemein gilt das Borland die Implementation von Random() ändern kann und man sich nicht darauf verlassen sollte das Random() von Version zu Version exakt die gleichen Zufallszahlen erzeugt bei gleichem Seed. Bisher erzeugt aber Random() seit Borland Pascal 4 immer die gleichen Sequenzen.
Auf alle Fälle kann es meiner Meinung aber nicht stimmen das die RTL von Delphi 7 nun automatisch Randomize() aufruft und somit bei jedem Start der Anwendung andere Zufallssequenzen erzeugt werden. Dies widerspräche dem Konzept eines Pseudo-Zufalls-Generators !! Wie gesagt ich meine das Random() ohne dem Aufruf von Randomize() in jeder Delphi Version die gleichen Sequenzen erzeugen muß. Das müsste aber abgeprüft werden ob D7 da andere Wege geht.

Gruß Hagen

eroe 19. Mai 2004 17:30

Re: Zufallszahl ermiteln
 
nein nein, also du musst auch in d7 noch die randomize funktion aufrufen, um den vorgang zu initialisiern ! ich hab da glaub ich irgendwie was falsch verstanden, kP, is ja auch wurst ;)

negaH 19. Mai 2004 18:55

Re: Zufallszahl ermiteln
 
Ja das glaube ich auch.

Ein Pseudo-Zufalls-Generator wird initialisiert indem man seinen Seed mit einem Wert füllt. Im Grunde ist der Seed nur der letzte erzeugte Zufallswert, vereinfacht gesagt.
Da eine solche Zufalls-Funktion wie Random() eben die wichtige Eigenschaft der Reproduzierbarkeit der Zufallssequenzen besitzt, stellt die Funktion Randomize() nur ein Hilfsmittel dar um aus anderen Informationen einen "zufälligen" Seed zu erzeugen. Damit wird also erreicht das der Seed jedesmal anders ist. Nun, das ist aber meistens garnicht erwünscht, zB. bei Simulationen oder Statistichen Berechnungen. Den exakt da will man ja das die Simulation exakt reproduzierbar ist wenn man dies will. So gesehen muß Random() bei jedem Neustart der Anwendung erstmal immer die gleichen Sequenzen erzeugen. Erst wenn man dies nicht wünscht sollte man Randomize() aufrufen.

Generell kann man sagen das zufälliges Verhalten eines Programmcodes erstmal absolut unerwünscht ist. D.h. unter gleichen Bedingungen muß die Software EXAKT das gleiche Resultat liefern.

Gruß Hagen


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:37 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 by Thomas Breitkreuz