Zufallszahlen in C erzeugen include erzeugt abhngig von
Zufallszahlen in C erzeugen
#include erzeugt abhängig von der "stdafx. h" <stdlib. h> aktuellen Uhrzeit einen neuen Satz von Zufallszahlen <stdio. h> <time. h> Damit soll verhindert werden, dass bei einem erneuten Aufruf dieses Programms genau die gleichen Zufallszahlen kommen. int main(){ int zufallszahl 1; // srand bitte nur EINMAL aufrufen // ganz am Anfang !!!!!! srand((unsigned)time(NULL)); zufallszahl 1 = rand(); return 0; }
#include "stdafx. h" <stdlib. h> <stdio. h> <time. h> aus diesem Satz von Zufallszahlen wird mit rand() die nächste herausgeholt. rand() liefert eine ganze Zahl zurück. int main(){ int zufallszahl 1; // srand bitte nur EINMAL aufrufen // ganz am Anfang !!!!!! srand((unsigned)time(NULL)); zufallszahl 1 = rand(); return 0; Diese nimmt einen Wert zwischen 0 und } RAND_MAX (= 32767) an (je einschließlich).
Problem 1: Wie bekommt man aber Zufallszahlen aus der Menge {1, 2, 3, 4, 5, 6} um z. B. einen Würfel zu simulieren?
Zurück zur Grundschule: Man verteilt (gleichmäßig) eine bestimmte Anzahl Computer auf 6 Schüler. Wieviel Computer können dabei übrig bleiben (minimal und maximal)?
Es bleiben minimal 0 Computer und maximal 5 übrig. Man bekommt also eine Zahl zwischen 0 und 5.
Mathematisch: erg = anzahl % 6 wobei erg die Werte aus der Menge {0, 1, 2, 3, 4, 5} annehmen kann.
Was muss man mathematisch nur noch machen, daß erg Werte aus der Menge {1, 2, 3, 4, 5, 6} annehmen kann ?
Man muss zu erg die Zahl 1 dazu addieren, also: erg = anzahl % 6 + 1; Oder, wenn anzahl eine Zufallszahl sein soll: anzahl = rand() % 6 + 1;
#include "stdafx. h" <stdlib. h> <stdio. h> <time. h> int main(){ int zufallszahl; // srand bitte nur EINMAL aufrufen // ganz am Anfang !!!!!! srand((unsigned)time(NULL)); zufallszahl = rand()%6+1; return 0; Die Variable zufallszahl nimmt einen Wert aus } der Menge {1, 2, 3, 4, 5 , 6} an.
Problem 2: Wie bekommt man aber eine Zufallszahl (Fließkommazahl) zwischen 0 und 1 ? Um z. B. einen Dartspfeil zu simulieren, der innerhalb der Strecke des Zahlenstrahls zwischen 0 und 1 einschlägt.
Die größte Zufallszahl ist RAND_MAX (= 32767) Welche Werte kann der folgende Term annehmen? rand() / RAND_MAX Überlegen Sie dazu, welche Werte rand() annehmen kann!
rand() nimmt Werte zwischen 0 und RAND_MAX (= 32767) an. Also kann rand() / RAND_MAX folgende Werte annehmen:
0 / 32767 =0 1 / 32767 2 / 32767. . . 32765 / 32767 32766 / 32767 = 1
rand() / RAND_MAX nimmt zwar nicht alle Werte (unendlich viele) zwischen 0 und 1 an, sondern nur 32768 Werte. Das ist aber eine so gute Näherung, daß man damit arbeiten kann.
Problem 3: Eine zufällige Zufallszahl (Fließkommazahl) zwischen 0 und 1 können wir jetzt zwar erzeugen.
Aber wie kann man zu einer vorgegeben Zahl z eine Zufallzahl (Fließkommazahl) zwischen 0 und z erzeugen ? Dartspfeil soll innerhalb der Strecke des Zahlenstrahls zwischen 0 und z einschlagen!
Angenommen zv_0_1 sei eine Variable (Fließkommazahl), die zufällige Werte zwischen 0 und 1 annimmt. Welche Werte nimmt dann der folgende Ausdruck an (minimal und maximal)? zv_0_1 * z
zv_0_1 ist minimal 0, also: zv_0_1 * z = 0 zv_0_1 ist maximal 1, also: zv_0_1 * z = z Welche Werte nimmt zv_0_1 * z an, wenn zv_0_1 die folgenden Werte annimt: 0, 25 0, 75
zv_0_1 = 0, 25, also: zv_0_1 * z = 0, 25 z zv_0_1 = 0, 5, also: zv_0_1 * z = 0, 5 z zv_0_1 = 0, 75, also: zv_0_1 * z = 0, 75 z
Welche Werte durchläuft (durchwandert) also zv_0_1 * z wenn zv_0_1 alle Werte (Fließkommazahlen) zwischen 0 und 1 durchläuft ?
Alle Werte (Fließkommazahlen) zwischen 0 und z
#include "stdafx. h" <stdlib. h> <stdio. h> <time. h> // Rest kommt gleich
Warum ist der Wert von int main(){ zufallszahl immer double zufallszahl; 0 oder ganz selten 1? double z; // srand bitte nur EINMAL aufrufen // ganz am Anfang !!!!!! srand((unsigned)time(NULL)); // Für z könnte man auch einen Wert // über Tastatur eingeben. z=123456. 789; zufallszahl = rand()/RAND_MAX * z; return 0; Warum liefert } rand() / RAND_MAX * z keine Zufallszahl? Was ist falsch ?
Wie wird der int main(){ Ausdruck double zufallszahl; richtig? double z; // srand bitte nur EINMAL aufrufen // ganz am Anfang !!!!!! srand((unsigned)time(NULL)); // Für z könnte man auch einen Wert // über Tastatur eingeben. z=123456. 789; zufallszahl = rand()/RAND_MAX * z; return 0; } Weil rand() und RAND_MAX den Datentyp int hat und int / int wieder int ergibt (der Nachkommateil wird abgeschnitten). Da rand() / RAND_MAX <=1, wird der Nachkommateil abgeschnitten und 0 oder 1 bleibt übrig!
Datentypumwandlung: int main(){ int in double zufallszahl; umwandeln! double z; // srand bitte nur EINMAL aufrufen // ganz am Anfang !!!!!! srand((unsigned)time(NULL)); // Für z könnte man auch einen Wert // über Tastatur eingeben. z=123456. 789; zufallszahl = (double)rand()/(double)RAND_MAX*z; return 0; }
Problem 4: Eine zufällige Zufallszahl (Fließkommazahl) zwischen 0 und z können wir jetzt zwar erzeugen. Wir bezeichnen den Bereich, in dem die Zufallszahl vorkommt: [0 , z]
Aber wie kann man eine Zufallzahl (Fließkommazahl) zwischen l (wie linke Grenze) und r (wie rechte Grenze) erzeugen ? Wir bezeichnen den zugehörigen Bereich mit: [l , r]. Der Dartspfeil soll innerhalb [l , r ] einschlagen!
Idee: man verschiebt [0 , z] zum Bereich [l , r] bzw. umgekehrt [l , r] nach [0 , z] Genauer:
[l , r] wird um l nach links verschoben. Wie heißt dann der Bereich wo man ankommt ?
[l-l , r-l] = [0 , r-l] Wie erzeugt man aber Zufallszahlen zwischen 0 und r-l ? (siehe frühere Folie)
(double)rand() / (double)RAND_MAX*(r-l);
Um welchen Wert muß nun der zugehörige Bereich [0 , r-l] nach rechts verschoben werden, damit man zum Bereich [l , r] kommt ?
Da [l , r] = [0+l, r-l+l] muß [0 , r-1] um l nach rechts verschoben werden. Wie wird das programmtechnisch realisiert?
(double)rand() / (double)RAND_MAX*(r-l) + l;
- Slides: 35