Wenn Sie einen echten, ungezinkten Würfel in die Hand nehmen und ihn auf einen Tisch werfen, dann erhalten Sie in der Regel ein zufälliges Würfelergebnis zwischen 1 und 6. Das funktioniert immer dann, wenn Sie durch Ihren Wurf so viel Komplexität in das physikalische System aus Hand, Würfel und Tisch bringen, dass es sich einer Berechnung entzieht, zum Beispiel indem Sie dem Würfel mit Ihrem Wurf noch eine zusätzliche Drehung verpassen.

Sobald es aber berechenbar wird, etwa weil Sie den Würfel einfach auf den Tisch legen oder einen gezinkten Würfel verwenden, dann ist das Ergebnis nicht mehr zufällig, sondern eben berechenbar. Zufallszahlen, die in einem Computer erzeugt werden, sind aber nun leider immer berechenbar, denn sie sind ja berechnet – vielleicht mit sehr guten Algorithmen, aber berechnet sind sie doch. Daher sind von einem Computer erstellte Zufallszahlen immer nur Pseudozufallszahlen.

Bei Pseudozufallszahlen kommt es darum sehr auf die Qualität des Algorithmus an. Die verwendeten Algorithmen sind denen für kryptografische Verfahren nicht unähnlich, und gute Kryptographie gehört mit zu dem kompliziertesten, was Menschen programmieren können. Hier ist alt und abgehangen oft besser als neu und dreimal schlauer.

Von den vielen Alternativen, die Ihnen in Swift zur Verfügung stehen, empfehle ich Ihnen zwei: Eine für Ganzzahlen – die benötigen wir für’s Würfeln – und eine für Gleitkommazahlen. Beides sind C-Funktionen, die aus OS X Systembibliotheken stammen, eben alt und abgehangen, aber problemlos in Swift verwendbar.

Ein zufälliger Integer

Für eine zufällige Integerzahl verwenden Sie bitte die Funktion arc4random_uniform(N). Sie gibt eine zufällige Zahl zwischen 0 und N-1 zurück. N ist hierbei, ebenso wie der Rückgabewert, vom Typ UInt32. Anders als drand48 (siehe unten) benötigt arc4random_uniform(N) keinen Startwert (Seed), Sie können die Funktion also direkt benutzen.

Beispielsweise gibt arc4random_uniform(6) eine Zahl zwischen 0 und 5 zurück.

Angepasst auf unseren Würfelwurf ergibt sich folgende Codezeile:

let wurfErgebnis = arc4random_uniform(6) + 1

Die Konstante wurfErgebnis wird hierbei von Swift als UInt32 inferiert.

Ein zufälliger Double

Die Funktion drand48() gibt einen Double zwischen [0.0, 1.0) zurück. Die mathematische Schreibweise mit einer eckigen und einer runden Klammer um das Intervall bedeutet, dass 0.0 zurückgegeben werden kann, 1.0 aber nicht (nur Zahlen sehr sehr nah an 1).

Diese Funkton benötigt aber einen Seed, einen Startwert, bevor sie verwendet werden kann. Üblicherweise verwendet man dafür die aktuelle Systemzeit, so dass der Seed bei jedem Programmstart unterschiedlich ist. Die C-Funktion time(..) gibt, wenn der Parmeter nil ist (sie also praktisch ohne Parameter aufgerufen wird), die Anzahl der Sekunden seit dem 1. Januar 1970 um 0 Uhr zurück. Und der Seed für drand48() wird mit Hilfe der Funktion srand48(..) einmalig gesetzt, so dass der Aufruf insgesamt lautet:

srand48(time(nil))
let doubleWurfErgebnis = drand48()

Beitragsbild: Ricky Jay dice in exhibit von Susan Gerbic in abgewandelter Form (CC BY SA 3.0)

Projekt Zufall 9: Zufallszahlen

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.