Zufallszahlen in C

Ein Computer kann genaugenommen keine "echten" Zufallszahlen generieren.
Programmierter Zufall ist ausreichend für statistische Gleichverteilung aber nicht identisch mit natürlichem Zufall.
Programmiersprachen bedienen sich vordefinierter Konstanten, aus denen Zahlenfolgen berechnet werden. Hierbei entsteht die Problematik, dass sich nach einer Anzahl von Aufrufen die Zahlenfolge schlichtweg wiederholt.
Daher wird empfohlen, zum Beginn eines Programms die Funktion srand() mit der Systemzeit time(NULL) als Parameter aufzurufen. Diese Funktion initialisiert den Index des Random-Generators ("seed") und mischt sozusagen die Karten neu für eine weitere berechnete Folge von Zufallszahlen.


Die rand()-Funktion in C akzeptiert keine Parameter zur Eingrenzung des Bereiches, aus dem die zurückgegebene Zahl stammen soll (anders als z.B. in PHP).
Um das zu realisieren, stehen verschiedene Möglichkeiten offen:

Führen Sie rand() in einer Schleife aus und überprüfen Sie nach jedem Durchlauf, ob die zurückgegebene Zahl im gewünschten Bereich liegt. Wenn ja, so kann sie zurückgegeben werden.
Diese Variante ist allerdings ausdrücklich nicht zu empfehlen, da sehr rechenintensiv und es sehr lange dauern kann, bis eine Zahl die gestellten Kriterien erfüllt.

Effizienter ist die Verwendung des Modulo-Operators:
Teilen Sie eine von rand() zurückgegebene Zahl durch den gewünschten Maximalwert, den eine Zufallszahl annehmen können soll (z.B. 9) und verwenden Sie den Restwert zur Rückgabe.
Dieser Rest (ermittelt durch Modulo) liegt immer zwischen 0 und dem Maximalwert, da bei der Division einer Zahl durch den Maximalwert der Rest niemals größer als dieser Max-Wert sein kann.
num = rand() % max;
Hierbei tritt das Problem auf, dass die erzeugte Folge von Zufallszahlen statistisch gesehen nicht gleich verteilt ist. Um dem Abhilfe zu schaffen, ist folgende Methode allgemein üblich:
Teilen Sie die von rand() zurückgegebene Zahl durch RAND_MAX, also die vom System vorgegebene Höchstgrenze für Zufallszahlen.
Das Ergebnis ist eine gebrochene Zahl zwischen 0 und 1.
Multiplizieren Sie diese mit dem gewünschten Maximalwert, erhalten Sie eine Zahl zwischen 0 und dem festgelegten Maximalwert.
Dabei handelt es sich um eine Gleitkommazahl, die noch gerundet oder in Integer konvertiert werden muss.
Mit dieser Methode ist stets das ganze mögliche Spektrum von Zufallszahlen (von 0 bis RAND_MAX) berücksichtigt, bloß eben auf den gewünschten Bereich "skaliert".
num = (int)((max + 1.0) * rand() / RAND_MAX);
Die 2. und 3. Methode geben nur Zahlen im Bereich von 0 bis max zurück.
Benötigt man Zahlen zwischen n und max (für n < max), kann n einfach zur erzeugten Zahl addiert werden:
num = n + (int)((max + 1.0) * rand() / RAND_MAX);

max sollte aus zwei Gründen um 1.0 erhöht werden:
Das erste Element ist 0; deshalb würden immer nur Zufallszahlen kleiner als der Maximalwert generiert werden.
Die Zahlen aus rand() und MAX_RAND sind beide vom Typ Integer. Ihr Quotient ist deshalb in dem Fall nur entweder 0 oder 1. Um eine Gleitkommazahl zu erhalten, muss einer der Operanden Double-formatiert sein. Das ist mit dem Double-Literal 1.0 gegeben.
Buchcover