Rheinwerk Computing < openbook > Rheinwerk Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

 <<   zurück
JavaScript und AJAX von Christian Wenz
Das umfassende Handbuch
Buch: JavaScript und AJAX

JavaScript und AJAX
839 S., mit DVD, 39,90 Euro
Rheinwerk Computing
ISBN 3-89842-859-1
gp Kapitel 6 Zufall
  gp 6.1 Zufallszahlen erstellen
    gp 6.1.1 JavaScript-Zufallszahlen
    gp 6.1.2 HP-Verfahren
    gp 6.1.3 Datumswert
  gp 6.2 Hilfsfunktionen
    gp 6.2.1 Zufallszahl aus einem Bereich
  gp 6.3 Anwendungsbeispiele
    gp 6.3.1 Lottozahlen
    gp 6.3.2 Zufallsbanner

Das, wobei unsere Berechnungen versagen, nennen wir Zufall. – Albert Einstein

Kapitel 6 Zufall

Wenn Sie den Zufallsbegriff streng mathematisch auslegen, ist ein Computer gar nicht in der Lage, einen »Zufall« zu produzieren. Der Grund liegt auf der Hand: Ein Computer kann keine Zufallszahl aus irgendwelchen (tatsächlichen) Stromschwankungen ermitteln, sondern muss diese auf Basis eines Algorithmus berechnen.

Dennoch ist ein Computer in der Lage, relativ zufällige Zahlenfolgen zu produzieren. Es gibt eine Reihe von Methoden, um zufällige Zahlenfolgen zu bestimmen. Das Problem bei solchen Methoden ist jedoch immer der Startwert.

Wir stellen in diesem Kapitel einige Möglichkeiten vor, wie Sie selbst Zufallszahlen erzeugen können. Als Nächstes programmieren wir einige Hilfsfunktionen, die Ihnen einen schnellen Zugriff auf die Zufallszahlen ermöglichen. Am Ende des Kapitels zeigen wir noch einige Beispielapplikationen, die mit Zufallszahlen (und JavaScript) erstellt werden können.

Fast die komplette benötigte Funktionalität steckt in dem Math-Objekt von JavaScript, unter anderem die Ermittlung einer Zufallszahl und das Runden von Zahlen.


Rheinwerk Computing

6.1 Zufallszahlen erstellen  downtop

Bei der Ermittlung einer Zufallszahl haben Sie die freie Auswahl: Entweder Sie bedienen sich bei den mitgelieferten Funktionalitäten, oder Sie programmieren Ihren eigenen Zufallsgenerator.


Rheinwerk Computing

6.1.1 JavaScript-Zufallszahlen  downtop

Seit den Anfängen von JavaScript gibt es die Methode Math.random(), die eine (ziemlich) zufällige Zahl zwischen 0 und 1 zurückliefert. Die Browser bedienen sich hierbei eines internen Algorithmus. Als Startwert für diesen Algorithmus verwenden die Browser veränderliche Daten wie beispielsweise die aktuelle Uhrzeit sowie (bei manchen Algorithmen) benutzerspezifische Daten wie etwa den freien Speicher auf der Festplatte oder die MAC-Adresse der Netzwerkkarte.

Es ist nicht weiter schlimm, dass Math.random() eine Fließkommazahl zwischen 0 und 1 zurückliefert. Wenn Sie eine ganzzahlige Zufallszahl innerhalb eines bestimmten Bereichs haben möchten, können Sie aus der Fließkommazahl eine ganze Zahl ermitteln, behalten dabei aber das Zufallsmoment bei (mehr dazu später im Kapitel).


Rheinwerk Computing

6.1.2 HP-Verfahren  downtop

Das HP-Verfahren ist nach der amerikanischen Firma Hewlett-Packard benannt, die vor allem für ihre Tintenstrahl- und Laserdrucker bekannt ist. Die Entwicklungsabteilung der Firma hat der Legende nach den Algorithmus entwickelt (sie empfiehlt ihn zumindest vehement und baut ihn angeblich auch in die eigenen Produkte ein).

Der Algorithmus funktioniert folgendermaßen:

gp  Man beginne mit einer Zahl zwischen 0 und 1.
gp  Man addiere zu dieser Zahl die Kreiszahl p (etwa 3,14159265...).
gp  Das Ergebnis potenziere man mit 8 (umgangssprachlich: Das Ergebnis »hoch 8« nehmen).
gp  Der Nachkommaanteil des Ergebnisses ist die nächste Zufallszahl.
gp  Mit dem Nachkommateil starte man den Algorithmus erneut, um eine weitere Zufallszahl zu erhalten.

Es ist mathematisch nachgewiesen, dass dieser Algorithmus die (mathematischen) Bedingungen für einen Zufallsgenerator erfüllt; die entstehende Zahlenfolge ist tatsächlich zufällig.

Was uns fehlt, ist ein Startwert zwischen 0 und 1. Mit Math.random() ließe sich einer bestimmen, aber das würde die Grundidee unseres Vorgehens konterkarieren. Stattdessen setzen wir hier eine andere, weitere Methode zur Bestimmung einer Zufallszahl ein – auch wenn die nicht ganz so geeignet ist wie beispielsweise Math.random().

Mit dem Date-Objekt aus dem vorherigen Kapitel können Sie auf das aktuelle Datum und die aktuelle Uhrzeit zugreifen. Die Methode getTime() liefert die so genannte Epochenzeit zurück. Das ist die Anzahl der seit dem 1. Januar 1970, Mitternacht, verstrichenen Millisekunden.

Diese Zahl ist mehr oder wenig zufällig und damit ein besonders geeigneter Zufallswert für unsere Zwecke. Werfen wir einen Blick auf einen dieser Datumswerte: Rufen Sie dazu in Ihrem Browser die Pseudo-URL javascript:alert(new Date().getTime()) auf.

Abbildung
Hier klicken, um das Bild zu Vergrößern

Abbildung 6.1     Das ist tatsächlich eine Uhrzeit.

Als Startwert benötigen Sie aber eine Zahl zwischen 0 und 1. Aus diesem Grund müssen Sie vor die lange Zahl »0.« schreiben, um diese möglichst schnell in eine Fließkommazahl umzuwandeln.

Bevor der Zeitwert in eine Fließkommazahl umgewandelt wird, ist noch eine weitere Überlegung erforderlich. Wenn Sie die Zufallszahlengenerierung mehrmals hintereinander aufrufen, ähneln sich die ersten Zufallszahlen sehr, denn der Startwert ändert sich dort erst circa in der achten Nachkommastelle. Aus diesem Grund ist es eine gute Idee, das Ergebnis von getTime() umzudrehen, also die letzte Ziffer als erste Nachkommastelle zu verwenden, die vorletzte Ziffer als zweite Nachkommastelle und so weiter. Da viele Browser als letzte Ziffer von getTime()immer »0« liefern, ignorieren wir die letzte Ziffer vollständig.

var t = new Date().getTime();
var t2 = "";
for (var i=2; i<=t.length; i++) {
   t2 += t.charAt(t.length-i);
}
eval("var z = 0." + t2);

Am Ende enthält die Variable z eine (recht zufällige) Zahl zwischen 0 und 1.

Nun kann der Rest des Algorithmus programmiert werden: Zur Zahl wird p hinzuaddiert (p steht bei JavaScript in der Eigenschaft Math.PI zur Verfügung):

z += Math.PI;

Dann wird das Ergebnis mit 8 potenziert – mit der Methode pow() des Math-Objekts:

z = Math.pow(z, 8);

Die neue Zufallszahl ist dann der Nachkommaanteil des Ergebnisses – das ermitteln Sie mit der Methode floor() des Math-Objekts:

z -= Math.floor(z);

Das Gegenstück zu floor() ist die Methode ceil() – die rundet nämlich ab.

Die folgende Funktion fasst dieses Vorgehen zusammen. Die jeweils letzte Zufallszahl wird in einer globalen Variablen gespeichert, damit sie beim nächsten Aufruf der Funktion wieder als Startwert verwendet werden kann.

var zufall_hp_zahl = 0;
function zufall_hp() {
   if (zufall_hp_zahl == 0) {
      var t = new Date().getTime().toString();
      var t2 = "";
      for (var i=2; i<=t.length; i++) {
         t2 += t.charAt(t.length-i);
      }
      eval("zufall_hp_zahl = 0." + t2 + ";");
   }
   zufall_hp_zahl += Math.PI;
   zufall_hp_zahl = Math.pow(zufall_hp_zahl, 8);
   zufall_hp_zahl -= Math.floor(zufall_hp_zahl);
   return zufall_hp_zahl;
}

Rheinwerk Computing

6.1.3 Datumswert  toptop

Betrachten Sie noch einmal, was der Browser bei der Eingabe der Pseudo-URL javascript:alert(new Date().getTime()) ausgibt (siehe auch Abbildung 6.1). Sie erhalten eine recht lange Zahl, die offensichtlich immer auf 0 endet. Das hat mit den browserinternen Abläufen zu tun sowie mit der Unfähigkeit, auf die Millisekunde genau zu messen. Für Sie entscheidend ist aber, dass Sie diesen Wert durch 10 teilen sollten, um eine »zufälligere« Zahl zu erhalten:

var z = new Date().getTime();
z = Math.round(z / 10);

Wenn Sie nun eine ganzzahlige Zufallszahl benötigen, gibt es eine einfache Möglichkeit, diese zu ermitteln. Verwenden Sie die Modulo-Rechnung!

Unter Modulo versteht man den Rest, den eine Division liefert. Unter JavaScript ist der Modulo-Operator %. 15  % 7 liefert als Ergebnis 1, denn bei der Division von 15 durch 7 bleibt als Rest 1 übrig (15 = 2 × 7 + 1).

Ein wenig mathematischer: Der Rest bei einer Division durch N ist eine Zahl zwischen 0 und N-1. Wenn Sie also eine Zufallszahl zwischen 0 und N haben möchten, können Sie wie folgt vorgehen:

var z = new Date().getTime();
z = Math.round(z / 10);
z %= n;

Die folgende Funktion setzt dieses Vorgehen allgemein für die Aufgabenstellung »berechne eine Zufallszahl zwischen a und b« um.

function zufall_datum(a, b) {
   var spanne = b – a + 1; // Länge des Intervalls
   var z = new Date().getTime();
   z = Math.round(z / 10);
   z %= spanne;  // z ist zwischen 0 und spanne-1
   z += a; // z ist nun zwischen a und b
   return z;
}
 <<   zurück
  
  Zum Rheinwerk-Shop
Neuauflage: JavaScript
Neuauflage: JavaScript
bestellen
 Ihre Meinung?
Wie hat Ihnen das Openbook gefallen?
Ihre Meinung

 Buchtipps
Zum Rheinwerk-Shop: jQuery






 jQuery


Zum Rheinwerk-Shop: Einstieg in JavaScript






 Einstieg in JavaScript


Zum Rheinwerk-Shop: Responsive Webdesign






 Responsive Webdesign


Zum Rheinwerk-Shop: Suchmaschinen-Optimierung






 Suchmaschinen-
 Optimierung


 Lieferung
Versandkostenfrei bestellen in Deutschland, Österreich und der Schweiz
InfoInfo




Copyright © Rheinwerk Verlag GmbH 2007
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das Openbook denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt.
Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


Nutzungsbestimmungen | Datenschutz | Impressum

Rheinwerk Verlag, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, service@rheinwerk-verlag.de

Cookie-Einstellungen ändern