Generieren Sie eine Zufallszahl zwischen zwei Zahlen in JavaScript

1797

Gibt es eine Möglichkeit, eine Zufallszahl in einem bestimmten Bereich (z. B. von 1 bis 6: 1, 2, 3, 4, 5 oder 6) in JavaScript zu generieren?

Mirgorod
quelle
12
Math.floor (Math.random () * 7)
Amjad Masad
65
Sicher .. Math.floor (Math.random () * 6 + 1)
Amjad Masad
3
Nabil Kadimi schrieb einen Artikel darüber, wie man auch negative Zufallszahlen erzeugt .
Madc
Hier ist eine nützliche Zusammenfassung: gist.github.com/kerimdzhanov/7529623
Dan KK
Warum Math.floor((Math.random()*10)+1);funktioniert eine solche Lösung nicht für Sie, wie hier unter w3schools.com/jsref/jsref_random.asp angegeben ?
Shashwat

Antworten:

2116

Wichtig

Der folgende Code funktioniert nur, wenn der Mindestwert ist 1. Es funktioniert nicht für andere Mindestwerte als 1.

Wenn Sie eine zufällige Ganzzahl zwischen 1 ( und nur 1 ) und 6 erhalten möchten, würden Sie Folgendes berechnen:

Math.floor(Math.random() * 6) + 1  

Wo:

  • 1 ist die Startnummer
  • 6 ist die Anzahl der möglichen Ergebnisse (1 + Start (6) - Ende (1) )
khr055
quelle
45
Während dies funktionieren würde, @Mike, wäre es am besten, auf die allgemeinere Version hinzuweisen, wie Francisc sie unten hat :-).
Raymond Machira
58
-1. Nach dem Googeln fand ich diese Frage. Der Titel lautet "" Zufälligen Wert zwischen zwei Zahlen in Javascript generieren "." Funktioniert nicht, wenn der
Mindestwert
18
Funktioniert nicht, wenn Sie eine Zahl zwischen zwei größeren Zahlen möchten, z. Math.floor (Math.random () * 900) + 700
Rob
14
Das funktioniert nur, wenn das Minimum 1 ist. Wenn das Minimum 2 ist und wir immer noch verwenden, Math.floor(Math.random() * 6) + 2bedeutet dies, dass bei einem Math.random()Ergebnis von 0,99 unser Zufallswert7
antitoxisch
27
Dieser Code ist nicht gut, weil er mit keiner Nummer funktioniert. @ Francis-Code ist der richtige.
König der Löwen
2285
function randomIntFromInterval(min, max) { // min and max included 
  return Math.floor(Math.random() * (max - min + 1) + min);
}

Was es "extra" macht, ist, dass es zufällige Intervalle zulässt, die nicht mit 1 beginnen. So können Sie beispielsweise eine Zufallszahl von 10 bis 15 erhalten. Flexibilität.

Francisc
quelle
5
Dies ist auch großartig, denn wenn jemand das toArgument nicht enthält , fromverdoppelt sich das Argument als das Maximum
Jason
12
Hallo. Dies ist von MDN: Returns a floating-point, pseudo-random number in the range [0, 1) that is, from 0 (inclusive) up to but not including 1 (exclusive), which you can then scale to your desired range.( developer.mozilla.org/en-US/docs/JavaScript/Reference/… )
Francisc
5
Lesen Sie den obigen Kommentar. Zufall ist innerhalb von [0,1), nicht [0,1].
Francisc
3
Funktioniert hervorragend, wenn die niedrigere Zahl 0 ist.
Robin Zimmermann
2
Beachten Sie, dass diese Lösung nur dann korrekt ist, wenn min und max ganze Zahlen sind. Andernfalls erhalten Sie ein Ergebnis im Intervall [min, lid (max)]. Dh Sie können ein Ergebnis erhalten, das außerhalb des Bereichs liegt, weil es höher als max ist.
Collimarco
328

Math.random ()

Gibt eine ganzzahlige Zufallszahl zwischen min ( enthalten ) und max ( enthalten ) zurück:

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

Oder eine beliebige Zufallszahl zwischen min ( enthalten ) und max ( nicht enthalten ):

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 erinnert zu werden (Mozilla):

Math.random () bietet keine kryptografisch sicheren Zufallszahlen. Verwenden Sie sie nicht für Sicherheitszwecke. Verwenden Sie stattdessen die Web Crypto API und genauer die window.crypto.getRandomValues ​​() -Methode.

Lior Elrom
quelle
Etwas, das mich verwirrt hat ... der Math.floor (..) stellt sicher, dass die Zahl eine ganze Zahl ist, bei der Math.round (..) eine ungleichmäßige Verteilung ergibt. Ref: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
alikuli
1
Ich vertraue dieser Antwort. Kann jemand einen Link oder eine klare Erklärung geben, warum dies funktioniert? Vielleicht ein Beispiel dafür, wie Math.round eine Tendenz ergibt, und warum das bedeutet, dass wir diese ziemlich komplex wirkende Formel verwenden müssen?
Robin Andrews
6
@alikuli Für eine Reihe von [1,2], gibt es 25% ige Chance , Math.random()Sie würde eine Zahl von einer von diesen [0,0.49], [0.5,0.99], [1,1.49], [1.5,1.99]. Das Runden dieser Intervalle würde zu 0, 1, 1, 2 führen, was keine gleichmäßige Verteilung ist. Bodenbelag sie ergibt 0, 0, 1, 1.
pishpish
1
@shuji Dies ist unter anderem die richtige Antwort. Ich wollte nur klären, warum die Verwendung von Math.roundover Math.floorzu unterschiedlichen Ergebnissen führen würde.
Pishpish
Die genaueste Lösung, die ich gefunden habe: function getRandomInt(min, max) { return Math.round((min - 0.5) + Math.random() * (max - min + 1)); }
Sadik
91

Andere Lösungen:

  • (Math.random() * 6 | 0) + 1
  • ~~(Math.random() * 6) + 1

Versuchen Sie es online

Vishal
quelle
6
Würde es Ihnen etwas ausmachen, die ~~ Sintaxis zu erklären (oder Hinweise darauf zu geben)? Ich habe es noch nie gesehen! Elegante Lösung, aber schwer zu verstehen.
DiegoDD
27
Double Tilde ~~a und Bitwise OR (a | 0) sind schnellere Möglichkeiten, Math.floor (a) zu schreiben
edi9999
7
a | 0ist auch die schnellste und am besten optimierte Methode, um eine Zeichenfolge in eine Ganzzahl umzuwandeln. Es funktioniert nur mit Zeichenfolgen, die Ganzzahlen ( "444"und "-444") enthalten, dh keine Gleitkommazahlen / Brüche. Es ergibt ein 0für alles, was fehlschlägt. Dies ist eine der Hauptoptimierungen hinter asm.js.
Pilau
3
Hinweis: Wenn Sie mit einigen wirklich großen Zahlen arbeiten, funktioniert die doppelte Tilde nicht. Versuchen Sie ~~(Math.random() * (50000000000000 - 0 + 1)) + 0undMath.floor(Math.random() * (50000000000000 - 0 + 1)) + 0
BrunoLM
3
"Double Tilde und Bitwise OR / sind schnellere Möglichkeiten, um Math Dot Floor zu schreiben" ist ein wunderschönes Reim-Couplet, das meinen Morgen aufgehellt hat. Danke @ edi9999!
Teedyay
60

TL; DR

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

Um die Zufallszahl zu erhalten generateRandomInteger(-20, 20);

ERKLÄRUNG UNTEN

Wir müssen eine zufällige ganze Zahl erhalten, sagen wir X zwischen min und max.

Recht?

dh min <= X <= max

Wenn wir min von der Gleichung subtrahieren, ist dies äquivalent zu

0 <= (X - min) <= (max - min)

Multiplizieren wir dies nun mit einer Zufallszahl r, die ist

0 <= (X - min) * r <= (max - min) * r

Fügen wir nun min wieder zur Gleichung hinzu

min <= min + (X - min) * r <= min + (max - min) * r

Wählen wir nun eine Funktion, die zu r führt, so dass sie unseren Gleichungsbereich als [min, max] erfüllt. Dies ist nur möglich, wenn 0 <= r <= 1

OK. Der Bereich von r ie [0,1] ist dem Ergebnis der Math.random () -Funktion sehr ähnlich. Ist es nicht?

Die Funktion Math.random () gibt eine Gleitkomma-Pseudozufallszahl im Bereich [0, 1) zurück. das heißt, von 0 (einschließlich) bis einschließlich 1 (exklusiv)

Zum Beispiel,

Fall r = 0

min+ 0 * ( max- min) = min

Fall r = 1

min+ 1 * ( max- min) = max

Zufälliger Fall mit Math.random 0 <= r <1

min+ r * ( max- min) = X , wobei X einen Bereich von min <= X < max hat

Das obige Ergebnis X ist eine Zufallszahl. Aufgrund von Math.random () ist unsere linke Grenze jedoch inklusive und die rechte Grenze ist exklusiv. Um unsere rechte Grenze einzuschließen, erhöhen wir die rechte Grenze um 1 und begründen das Ergebnis.

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

Um die Zufallszahl zu erhalten

generateRandomInteger(-20, 20);;

Faiz Mohamed Haneef
quelle
25

Oder in Unterstrich

_.random(min, max)
vladiim
quelle
24
var x = 6; // can be any number
var rand = Math.floor(Math.random()*x) + 1;
ryebr3ad
quelle
2
Tatsächlich. Ich habe vergessen, Rand war 0 inklusive. Repariert.
Roggenbr3ad
3
Das ist ein Teil von Pseudocode ... jemand könnte denken, dass es real ist und versuchen, es so zu verwenden.
Gravityboy
35
@gravityboy Worüber sprichst du? Wenn jemand [Nummer auswählen ...] nicht durch eine Nummer ersetzen kann, ist er möglicherweise nicht als Programmierer geeignet.
Roggenbr3ad
7
@ ryebr3ad -1! Es heißt in Javascript nicht im Pseudocode und auch nicht alle Leser sind versierte Programmierer. Viele sind Anfänger!
Steve
3
@ ryebr3ad: Ich hatte einen Kollegen, der Praktikanten über eine Datenbankumgebung unterrichtete, für die sie Unterstützung benötigen würden. Er sagte ihnen, sie sollten alles aus einer Tabelle auswählen und sie begannen direkt im SQL-Abfrage-Editor "Alles aus ... auswählen" zu schreiben. Er hatte die gleiche Reaktion wie Sie.
Ellesedil
22

jsfiddle: https://jsfiddle.net/cyGwf/477/

Random Integer : Um eine zufällige Ganzzahl zwischen minund zu erhalten max, verwenden Sie den folgenden Code

function getRandomInteger(min, max) {
  min = Math.ceil(min);
  max = Math.floor(max);
  return Math.floor(Math.random() * (max - min)) + min;
}

Zufällige Gleitkommazahl : Um eine zufällige Gleitkommazahl zwischen minund zu erhalten max, verwenden Sie den folgenden Code

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

Referenz: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random

Razan Paul
quelle
14

Mathematik ist nicht meine Stärke, aber ich habe an einem Projekt gearbeitet, bei dem ich viele Zufallszahlen zwischen positiv und negativ generieren musste.

function randomBetween(min, max) {
    if (min < 0) {
        return min + Math.random() * (Math.abs(min)+max);
    }else {
        return min + Math.random() * max;
    }
}

Z.B

randomBetween(-10,15)//or..
randomBetween(10,20)//or...
randomBetween(-200,-100)

Natürlich können Sie auch eine Validierung hinzufügen, um sicherzustellen, dass Sie dies nur mit Zahlen tun. Stellen Sie außerdem sicher, dass min immer kleiner oder gleich max ist.

Petter Thowsen
quelle
5
Das ist einfach falsch. min + Math.random() * maxgibt Ihnen Zahlen zwischen min und min + max, was nicht das ist, was Sie wollen. Der erste Zweig von ifist korrekt, könnte aber vereinfacht gesagt werden. Dies return min + Math.random() * (max - min)ist die richtige Lösung, unabhängig davon, ob min positiv oder negativ ist (siehe die anderen Antworten). Denken Sie auch daran, dass Sie das Ergebnis immer noch auf den Boden legen müssen, wenn Sie keine Brüche möchten.
Avish
10

Ich habe eine flexiblere Funktion geschrieben, die Ihnen Zufallszahlen geben kann, aber nicht nur Ganzzahlen.

function rand(min,max,interval)
{
    if (typeof(interval)==='undefined') interval = 1;
    var r = Math.floor(Math.random()*(max-min+interval)/interval);
    return r*interval+min;
}

var a = rand(0,10); //can be 0, 1, 2 (...) 9, 10
var b = rand(4,6,0.1); //can be 4.0, 4.1, 4.2 (...) 5.9, 6.0

Feste Version.

ElChupacabra
quelle
Dies ist keine gute Lösung, da sie nicht mit Null als Mindestwert funktioniert. Siehe die Antwort von @ Lior.
Sebastien
Natürlich funktioniert es mit Null als Mindestwert. Hast du versucht? Es gibt keinen Grund, warum es möglicherweise nicht funktioniert. Es funktioniert nicht mit 0 als Intervall, was nicht seltsam ist (Intervall = 0? ...).
ElChupacabra
Ich habe diese Funktion mehrmals mit Null als Mindestwert ausgeführt und in der Ausgabe nie Null erhalten. Oder ich habe nicht das Glück ...
Sebastien
Du hast recht. "+ Intervall" war an der falschen Stelle. Testen Sie es jetzt bitte. Seltsame Sache, dass mir console.log manchmal 0,300000004 statt 0,3 wie 3 * 0,1 gibt, wäre nicht genau 0,3.
ElChupacabra
9

Beispiel

Geben Sie eine Zufallszahl zwischen 1 und 10 zurück:

Math.floor((Math.random() * 10) + 1);

Das Ergebnis könnte sein: 3

Versuchen Sie es selbst: hier

- -

oder mit lodash / undescore:

_.random(min, max)

Docs: - lodash - undescore

Sebastián Lara
quelle
1
Du brauchst also 9 oder 10, oder? Wenn ja: const randomNumber = Math.floor ((Math.random () * 10) + 1) const nineOrTen = randomNumber% 2 === 0? 9: 10
Sebastián Lara
7

Trotz vieler Antworten und fast gleichem Ergebnis. Ich möchte meine Antwort hinzufügen und ihre Funktionsweise erklären. Weil es wichtig ist, die Funktionsweise zu verstehen, anstatt das Einfügen eines Zeilencodes zu kopieren. Das Generieren von Zufallszahlen ist nichts anderes als einfache Mathematik.

CODE:

function getR(lower, upper) {

  var percent = (Math.random() * 100);
  // this will return number between 0-99 because Math.random returns decimal number from 0-0.9929292 something like that
  //now you have a percentage, use it find out the number between your INTERVAL :upper-lower 
  var num = ((percent * (upper - lower) / 100));
  //num will now have a number that falls in your INTERVAL simple maths
  num += lower;
  //add lower to make it fall in your INTERVAL
  //but num is still in decimal
  //use Math.floor>downward to its nearest integer you won't get upper value ever
  //use Math.ceil>upward to its nearest integer upper value is possible
  //Math.round>to its nearest integer 2.4>2 2.5>3   both lower and upper value possible
  console.log(Math.floor(num), Math.ceil(num), Math.round(num));
}
Arun Sharma
quelle
6

Ich habe nach einem in TypeScript geschriebenen Zufallszahlengenerator gesucht und dies nach dem Lesen aller Antworten geschrieben. Ich hoffe, es würde für TypeScript-Codierer funktionieren.

    Rand(min: number, max: number): number {
        return (Math.random() * (max - min + 1) | 0) + min;
    }   
Erdi İzgi
quelle
5

Math.random() ist schnell und für viele Zwecke geeignet, aber nicht geeignet, wenn Sie kryptografisch sichere Werte benötigen (es ist nicht sicher) oder wenn Sie Ganzzahlen aus einer völlig einheitlichen unverzerrten Verteilung benötigen (der in anderen Antworten verwendete Multiplikationsansatz erzeugt bestimmte Werte etwas häufiger als andere).

In solchen Fällen können wir crypto.getRandomValues()sichere Ganzzahlen generieren und generierte Werte ablehnen, die wir nicht einheitlich dem Zielbereich zuordnen können. Dies ist langsamer, sollte jedoch nur dann von Bedeutung sein, wenn Sie eine extrem große Anzahl von Werten generieren.

Um das Problem der voreingenommenen Verteilung zu klären, betrachten Sie den Fall, in dem wir einen Wert zwischen 1 und 5 generieren möchten, aber einen Zufallszahlengenerator haben, der Werte zwischen 1 und 16 erzeugt (ein 4-Bit-Wert). Wir möchten, dass jedem Ausgabewert die gleiche Anzahl generierter Werte zugeordnet wird, aber 16 wird nicht gleichmäßig durch 5 geteilt: Es verbleibt ein Rest von 1. Wir müssen also 1 der möglichen generierten Werte ablehnen und erst fortfahren, wenn wir erhalten einer der 15 kleineren Werte, die einheitlich in unseren Zielbereich abgebildet werden können. Unser Verhalten könnte wie folgt aussehen: Pseudocode:

Generate a 4-bit integer in the range 1-16.
If we generated  1,  6, or 11 then output 1.
If we generated  2,  7, or 12 then output 2.
If we generated  3,  8, or 13 then output 3.
If we generated  4,  9, or 14 then output 4.
If we generated  5, 10, or 15 then output 5.
If we generated 16 then reject it and try again.

Der folgende Code verwendet eine ähnliche Logik, generiert jedoch stattdessen eine 32-Bit-Ganzzahl, da dies die größte gemeinsame Ganzzahlgröße ist, die durch den Standardtyp von JavaScript dargestellt werden kann number. (Dies kann geändert werden, um BigInts zu verwenden, wenn Sie einen größeren Bereich benötigen.) Unabhängig vom ausgewählten Bereich beträgt der Anteil der abgelehnten generierten Werte immer weniger als 0,5, sodass die erwartete Anzahl der Ablehnungen immer weniger als 1,0 und beträgt normalerweise nahe 0,0; Sie müssen sich keine Sorgen machen, dass es für immer eine Schleife gibt.

const randomInteger = (min, max) => {
  const range = max - min;
  const maxGeneratedValue = 0xFFFFFFFF;
  const possibleResultValues = range + 1;
  const possibleGeneratedValues = maxGeneratedValue + 1;
  const remainder = possibleGeneratedValues % possibleResultValues;
  const maxUnbiased = maxGeneratedValue - remainder;

  if (!Number.isInteger(min) || !Number.isInteger(max) ||
       max > Number.MAX_SAFE_INTEGER || min < Number.MIN_SAFE_INTEGER) {
    throw new Error('Arguments must be safe integers.');
  } else if (range > maxGeneratedValue) {
    throw new Error(`Range of ${range} (from ${min} to ${max}) > ${maxGeneratedValue}.`);
  } else if (max < min) {
    throw new Error(`max (${max}) must be >= min (${min}).`);
  } else if (min === max) {
    return min;
  } 

  let generated;
  do {
    generated = crypto.getRandomValues(new Uint32Array(1))[0];
  } while (generated > maxUnbiased);

  return min + (generated % possibleResultValues);
};

console.log(randomInteger(-8, 8));          // -2
console.log(randomInteger(0, 0));           // 0
console.log(randomInteger(0, 0xFFFFFFFF));  // 944450079
console.log(randomInteger(-1, 0xFFFFFFFF));
// Error: Range of 4294967296 covering -1 to 4294967295 is > 4294967295.
console.log(new Array(12).fill().map(n => randomInteger(8, 12)));
// [11, 8, 8, 11, 10, 8, 8, 12, 12, 12, 9, 9]

Jeremy Banks
quelle
Das nenne ich Overkill.
2xSamurai
2
@ 2xSamurai Dort habe ich die Antwort aktualisiert, um zu erklären, warum Sie dies möglicherweise benötigen und wie es funktioniert. Ist das besser? : P
Jeremy Banks
Es ist überhaupt kein Overkill, wenn Sie kryptografisch sichere und gleichmäßig verteilte Zufallszahlen wünschen. Es ist schwierig, Zufallszahlen zu generieren, die diese Anforderungen erfüllen. Tolle Antwort, @JeremyBanks.
Thomaskonrad
4

Hinzufügen floatmit einer Version mit fester Genauigkeit basierend auf der intVersion in der Antwort von @ Francisc:

function randomFloatFromInterval (min, max, fractionDigits) {
  const fractionMultiplier = Math.pow(10, fractionDigits)
  return Math.round(
    (Math.random() * (max - min) + min) * fractionMultiplier,
  ) / fractionMultiplier
}

damit:

randomFloatFromInterval(1,3,4) // => 2.2679, 1.509, 1.8863, 2.9741, ...

und für int Antwort

randomFloatFromInterval(1,3,0) // => 1, 2, 3
yonatanmn
quelle
3

Kryptostarke zufällige Ganzzahl im Bereich [a, b] (Annahme: a <b)

let rand= (a,b)=> a+(b-a+1)*crypto.getRandomValues(new Uint32Array(1))[0]/2**32|0

console.log( rand(1,6) );

Kamil Kiełczewski
quelle
1

Das sollte funktionieren:

const getRandomNum = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min
sbr_amd
quelle
1

Ich habe eine großartige neue Möglichkeit entdeckt, dies mit ES6-Standardparametern zu tun. Es ist sehr geschickt, da es entweder ein Argument oder zwei Argumente zulässt. Hier ist es:

function random(n, b = 0) {
    return Math.random() * (b-n) + n;
}
maburdi94
quelle
1

Dies ist ungefähr neun Jahre zu spät, aber randojs.com macht dies zu einem einfachen Einzeiler :

rando(1, 6)

Sie müssen dies nur zum Kopf Ihres HTML-Dokuments hinzufügen, und Sie können so ziemlich alles, was Sie wollen, mit Zufälligkeit leicht tun. Zufällige Werte von Arrays, zufällige Abfrageelemente, zufällige Eigenschaften von Objekten und sogar das Verhindern von Wiederholungen, falls erforderlich.

<script src="https://randojs.com/1.0.0.js"></script>
Aaron Plocharczyk
quelle
Warum eine Abhängigkeit hinzufügen, um etwas zu tun, das bereits ein Einzeiler ist? Die Besessenheit, Bibliotheken in der JS-Community hinzuzufügen, ist verrückt
Daniel Cooke
leichter zu lesen und zu merken. Ich stimme jedoch zu
Aaron Plocharczyk
1

Dies funktioniert für mich und erzeugt Werte wie die Standardbibliotheksfunktion random.randint von Python :


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

console.log("Random integer: " + randint(-5, 5));
gnrfan
quelle
1

Versuchen Sie es mit:

function random(min, max) {
   return Math.round((Math.random() *( Math.abs(max - min))) + min);
}
console.log(random(1, 6));

AyushKatiyar
quelle
1

1-6 wie ein Würfel im Grunde zurückgeben,

return Math.round(Math.random() * 5 + 1);
Husky931
quelle