2493 Stimmen

Generieren von zufälligen Ganzzahlen in JavaScript in einem bestimmten Bereich

Wie kann ich in JavaScript zufällige ganze Zahlen zwischen zwei festgelegten Variablen generieren, z. B. x = 4 und y = 8 würden jede der Zahlen 4, 5, 6, 7, 8 ausgeben?

2 Stimmen

Hier ist ein nützlicher Gist: gist.github.com/kerimdzhanov/7529623

15 Stimmen

Als kleine Anmerkung: Für diejenigen, die npm verwenden und nach einer schnellen, zuverlässigen und fertigen Lösung suchen, gibt es lodash.random, das mit einem super kleinen Footprint einfach erforderlich ist (es importiert nur die Methode selbst und nicht das gesamte lodash).

0 Stimmen

4788voto

Ionuț G. Stan Punkte 168218

Es gibt einige Beispiele auf der Mozilla Developer Network-Seite:

/**
 * Returns a random number between min (inclusive) and max (exclusive)
 */
function getRandomArbitrary(min, max) {
    return Math.random() * (max - min) + min;
}

/**
 * Returns a random integer between min (inclusive) and max (inclusive).
 * The value is no lower than min (or the next integer greater than min
 * if min isn't an integer) and no greater than max (or the next integer
 * lower than max if max isn't an integer).
 * Using Math.round() will give you a non-uniform distribution!
 */
function getRandomInt(min, max) {
    min = Math.ceil(min);
    max = Math.floor(max);
    return Math.floor(Math.random() * (max - min + 1)) + min;
}

Hier ist die Logik dahinter. Es ist eine einfache Regel von dreien:

Math.random() gibt eine Number zwischen 0 (inklusive) und 1 (exklusive) zurück. Also haben wir ein Intervall wie dieses:

[0 .................................... 1)

Jetzt möchten wir eine Zahl zwischen min (inklusive) und max (exklusive):

[0 .................................... 1)
[min .................................. max)

Wir können das Math.random verwenden, um den entsprechenden Wert im Intervall [min, max) zu erhalten. Aber zuerst sollten wir das Problem ein wenig vereinfachen, indem wir min vom zweiten Intervall subtrahieren:

[0 .................................... 1)
[min - min ............................ max - min)

Dies ergibt:

[0 .................................... 1)
[0 .................................... max - min)

Jetzt können wir Math.random anwenden und dann den entsprechenden Wert berechnen. Wählen wir eine zufällige Zahl:

                Math.random()
                    |
[0 .................................... 1)
[0 .................................... max - min)
                    |
                    x (was wir brauchen)

Um also x zu finden, würden wir folgendes tun:

x = Math.random() * (max - min);

Vergessen Sie nicht, min wieder hinzu zu addieren, sodass wir eine Zahl im Intervall [min, max) erhalten:

x = Math.random() * (max - min) + min;

Das war die erste Funktion von MDN. Die zweite Funktion gibt eine Ganzzahl zwischen min und max, beide inklusive, zurück.

Für Ganzzahlen könnten Sie round, ceil oder floor verwenden.

Sie könnten Math.round(Math.random() * (max - min)) + min verwenden, dies führt jedoch zu einer ungleichmäßigen Verteilung. Sowohl min als auch max haben nur ungefähr die Hälfte der Chance zu würfeln:

min...min+0.5...min+1...min+1.5   ...    max-0.5....max
 ...     Math.round()
   min          min+1                          max

Wenn max aus dem Intervall ausgeschlossen ist, hat es eine noch geringere Chance zu würfeln als min.

Mit Math.floor(Math.random() * (max - min +1)) + min haben Sie eine perfekt gleichmäßige Verteilung.

 min...  min+1...    ...      max-1... max....   (max+1 is excluded from interval)
 ...     Math.floor()
   min     min+1               max-1    max

Sie können ceil() und -1 nicht in dieser Gleichung verwenden, weil max jetzt eine leicht geringere Chance hat zu würfeln, aber Sie könnten auch das (unerwünschte) Ergebnis von min-1 würfeln.

1 Stimmen

Könnten Sie erklären, warum Sie eins zum Maximalwert hinzufügen müssen? Ich verstehe diesen Teil nicht.

18 Stimmen

Es tut das nur, weil es floor aufruft, das abrundet.

6 Stimmen

@thezachperson31 Du könntest round verwenden, aber dann hätten sowohl min als auch max nur halb so viel Chance zu rollen wie die anderen Zahlen. Du könntest auch eins abziehen und ceil verwenden. Dies führt jedoch dazu, dass die Zahl max aufgrund des Intervalls [0,1) minimal weniger Chancen hat zu rollen.

640voto

Darin Dimitrov Punkte 990883
var zufallszahl = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;

33 Stimmen

Ich weiß, dass dies eine SEHR alte Antwort ist, aber die Verwendung von (Math.random() * (maximum - minimum + 1) ) << 0 ist schneller.

23 Stimmen

@IsmaelMiguel Die Verwendung von binären Operatoren (x << 0, x | 0, ~~x) anstelle von Math.floor() konvertiert x in ein Zweikomplement mit einem viel kleineren Bereich als Number.MAX_SAFE_INTEGER (2³²¹ vs. 2³), daher müssen Sie es mit Vorsicht verwenden!

0 Stimmen

@IsmaelMiguel Yo, ich habe gerade deine Methode in der Konsole ausprobiert und zufällig einen negativen Wert bekommen! Math.randRange = (minimum, maximum) => (Math.random() * (maximum - minimum + 1) ) << 0 Math.randRange(2,657348096152) -1407373159

240voto

Lior Elrom Punkte 17362

Math.random()

Gibt eine ganzzahlige Zufallszahl zwischen min (einschließlich) und max (einschließlich) zurück:

function randomInteger(min, max) {
  return Math.floor(Math.random() * (max - min + 1)) + min;
}

Oder irgendeine Zufallszahl zwischen min (einschließlich) und max (nicht eingeschlossen):

function randomNumber(min, max) {
  return Math.random() * (max - min) + min;
}

Nützliche Beispiele (ganze Zahlen):

// 0 -> 10
Math.floor(Math.random() * 11);

// 1 -> 10
Math.floor(Math.random() * 10) + 1;

// 5 -> 20
Math.floor(Math.random() * 16) + 5;

// -10 -> (-2)
Math.floor(Math.random() * 9) - 10;

** Und immer schön daran erinnern (Mozilla):

Math.random() liefert keine kryptographisch sicheren Zufallszahlen. Verwenden Sie sie nicht für alles, was mit Sicherheit zu tun hat. Verwenden Sie stattdessen die Web Crypto API, genauer gesagt die window.crypto.getRandomValues() Methode.

5 Stimmen

Wenn Sie Math.ceil verwenden, kann +1 eingespart werden.

64voto

Gordon Gustafson Punkte 38406

Verwenden:

function getRandomizer(unten, oben) {
    return function() {
        return Math.floor( Math.random() * ( 1 + oben - unten ) ) + unten;
    }
}

Verwendung:

var rollDie = getRandomizer( 1, 6 );

var Ergebnisse = ""
for ( var i = 0; i<1000; i++ ) {
    Ergebnisse += rollDie() + " ";    // Erstellt einen String mit 1000 Zufallszahlen im Bereich 1-6.
}

Aufschlüsselung:

Wir geben eine Funktion zurück (entlehnt aus der funktionalen Programmierung), die beim Aufrufen eine zufällige Ganzzahl zwischen den Werten unten und oben, einschließlich, zurückgibt. Wir sagen 'einschließlich', weil wir sowohl unten als auch oben im Bereich der zurückgegebenen Zahlen einschließen wollen. Auf diese Weise wird getRandomizer( 1, 6 ) entweder 1, 2, 3, 4, 5 oder 6 zurückgeben.

('unten' ist die kleinere Zahl und 'oben' ist die größere Zahl)

Math.random() * ( 1 + oben - unten )

Math.random() gibt eine zufällige Dezimalzahl zwischen 0 und 1 zurück, und wenn wir sie mit eins plus der Differenz zwischen oben und unten multiplizieren, erhalten wir eine Dezimalzahl irgendwo zwischen 0 und 1+b-a.

Math.floor( Math.random() * ( 1 + oben - unten ) )

Math.floor rundet die Zahl auf die nächste Ganzzahl ab. Jetzt haben wir alle Ganzzahlen zwischen 0 und oben-unten. Die 1 sieht verwirrend aus, aber sie muss dort stehen, da wir immer abrunden, sodass die obere Zahl ohne sie niemals erreicht wird. Die zufällige Dezimalzahl, die wir generieren müssen, muss im Bereich von 0 bis (1+oben-unten) liegen, damit wir abrunden und eine Ganzzahl im Bereich von 0 bis oben-unten erhalten können.

Math.floor( Math.random() * ( 1 + oben - unten ) ) + unten

Der Code im vorherigen Beispiel hat uns eine Ganzzahl im Bereich von 0 und oben-unten gegeben, also müssen wir jetzt nur noch unten zu diesem Ergebnis hinzufügen, um eine Ganzzahl im Bereich von unten und oben einschließlich zu erhalten. :D


ANMERKUNG: Wenn Sie einen Nicht-Ganzzahlwert übergeben oder die größere Zahl zuerst angeben, erhalten Sie ein unerwünschtes Verhalten, aber es sei denn, es wird angefordert, werde ich nicht in den Argumentprüfungscode eintauchen, da er weit vom ursprünglichen Zweck der Frage entfernt ist.

1 Stimmen

Ich erkenne, dass dies etwa 2½ Jahre später ist, aber mit der Eingabe 1 und 6 gibt Ihre Funktion die Werte 1,2,3,4 und 5 zurück, aber nie eine 6, wie es der Fall wäre, wenn sie "einschließlich" wäre.

10 Stimmen

@some, Es könnte schlimmer sein, ich bin 2½ Jahre + 1 Tag später ^^

0 Stimmen

+1, ich habe Ihren Code getestet, es scheint einen korrekten Wert zu erstellen. Kreative Struktur zur Behandlung fester Szenarien, die im Code möglicherweise häufig wiederholt werden.

50voto

Shams Ansari Punkte 624

All diese Lösungen verwenden viel zu viele Ressourcen. Es reicht aus, nur eine Funktion aufzurufen: Math.random();

Math.random() * max | 0;

Dies gibt eine Zufallszahl zwischen 0 (inklusive) und max (exklusive) zurück.

2 Stimmen

Das ist so sauber. Vielen Dank!

2 Stimmen

Der OP fragte nach einem BEREICH zwischen 4 & 8, nicht 8 und 0

4 Stimmen

Dann funktioniert es nicht. Math.random() * 10 | 5 gibt nur 5 | 7 | 13 aus

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X