Neuer Artikel: Zufallszahlen in JavaScript erzeugen

Die Erzeugung von Zufallszahlen in JavaScript scheint ein Minenfeld zu sein: Die Funktion Math.random() liefert bloß eine Kommazahl zwischen 0 und 1. Das ist selten gewünscht, sodass das Ergebnis auf einen anderen Zahlenbereich projiziert und in eine ganze Zahl umgewandelt werden muss.

Leider erfreut sich eine äußerst problematische Lösung mit Math.round() großer Verbreitung. Sie liefert nicht wirklich zufällige Zahlen aus einem gewünschten Zahlenbereich, sondern benachteiligt die erste und letzte Zahl. Ein neuer Artikel auf SELFHTML aktuell diskutiert dieses Thema:

Gleich verteilte Zufallszahlen in JavaScript erzeugen

Der Artikel stellt nichts grundlegendes Neues vor, sondern bietet eine kompakte Anwort auf eine häufige Fragestellung. Er erklärt die Unzulänglichkeiten der Umsetzung mit Math.round() und stellt dieser eine bessere Umsetzung mit Math.floor() entgegen. Diese findet man zwar glücklicherweise in immer mehr JavaScript-Dokumentationen, aber durchgesetzt hat sie sich offenbar noch nicht.

Wenn das nächste Mal Bücher verlost werden und der JavaScript-Zufallsgenerator entscheiden soll: Bitte nicht Math.round(), sondern Math.floor() verwenden. 😉

9 Kommentare » Schreibe einen Kommentar

  1. Ich habe die Lösung von Michael soeben übernommen und es funktioniert! 😉

    Allerdings frage ich mich wieso 0,5 subtrahiert werden muss? Ohne scheint es auch zu funktionieren… – Habe ich etwas wichtiges übersehen?!

  2. Bei der Anmerkung zur Korrektur der Math.round-Variante hat sich ein Fehler in die Formel eingeschlichen:

    statt: var x = Math.round(Math.random() * (max – min + 1)) + min – 0.5;

    muss es richtig heißen: var x = Math.round(Math.random() * (max – min + 1) – 0.5) + min

    Wie es auch im Text vorher beschrieben wird, muss die Subtraktion vor dem Runden stattfinden.

  3. Horst, auch dann hast du ein Problem. Random generiert Zahlen von 0 bis gerade unter 1. Du kriegst dann also in ganz seltenen Fällen auch eine 0 als Lottozahl.

    Nicht round und nicht ceil, floor ist die richtige Methode. Für Zahlen von 1-49 macht man das so:

    a = Math.floor(Math.random() * 49) + 1;

  4. Hallo,

    ich mache meine Lottozahlen so:

    a = Math.random();
    a *= 49;
    a = Math.ceil(a);

    Viele Grüße,
    Hotte

  5. Ups, durch die Einführung der Intervallschreibweise sollte das natürlich unnötig sein. (Ich hatte das nachträglich nochmal umgekrempelt.) Danke für den Hinweis.

    Übrigens ändere ich innerHTML von tbody. Aber ich werde mir das mal ansehen. (Nachtrag: Ihr habt Recht. Auch für tbody ist innerHTML im IE nur lesbar.)

  6. innerHTML ist m.W. im IE bei tr/td readonly.

    Andere Anmerkung:
    Am Anfang wird die Intervallschreibweise vorgestellt.
    Ziemlich am Ende ist die Tabelle dann aber so dargestellt:
    0 bis 1 1 bis 2 usw. statt [0;1[ [1;2[ usw.
    Erscheint mir inkonsequent, insb. weil das "bis" ja sehr schwammig ist, was die Anfangs- und Endwerte betrifft.

  7. Siechfried: Kleiner Hinweis von mir: Es muss heißen "…dieses Themas angenommen hat". 😉
    *wegduck*

  8. Sehr schön, dass sich mal jemand diesem Thema angenommen hat. Kleiner Hinweis von mir: Die Demonstration bricht im IE 7 ergebnislos und mit einer gewohnt aussagearmen Fehlermeldung ab ("Unbekannter Laufzeitfehler, Zeile 308, Zeichen 3"). Ich tippe ins Blaue hinein auf die Kombination aus innerHTML und <tr>/<td> ohne expliziten <tbody>. Evtl. wäre insertRow und insertCell der Vorzug zu geben.