Genera un numero casuale tra due numeri in JavaScript


1798

Esiste un modo per generare un numero casuale in un intervallo specificato (ad es. Da 1 a 6: 1, 2, 3, 4, 5 o 6) in JavaScript?


12
Math.floor (Math.random () * 7)
Amjad Masad,

65
Certo .. Math.floor (Math.random () * 6 + 1)
Amjad Masad

3
Nabil Kadimi ha scritto un articolo su come generare anche numeri casuali negativi .
madc,

ecco un utile riassunto
Dan KK

perché una soluzione come questa Math.floor((Math.random()*10)+1);non può funzionare per te come specificato qui su w3schools.com/jsref/jsref_random.asp ..?
Shashwat,

Risposte:


2118

Importante

Il codice seguente funziona solo se il valore minimo è 1. Non funziona con valori minimi diversi da 1.

Se desideri ottenere un numero intero casuale compreso tra 1 ( e solo 1 ) e 6, dovresti calcolare:

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

Dove:

  • 1 è il numero iniziale
  • 6 è il numero di risultati possibili (1 + inizio (6) - fine (1) )

45
Mentre questo funzionerebbe, @Mike, sarebbe meglio sottolineare la versione più generica come Francisc l'ha sotto :-).
Raymond Machira,

59
-1. Dopo aver cercato su Google ho trovato questa domanda, il titolo è "" Genera valore casuale tra due numeri in Javascript "." Non funzionerà se il valore minimo è 0
Ydhem

18
Non funziona se si desidera un numero compreso tra due numeri più grandi, ad es. Math.floor (Math.random () * 900) + 700
Rob

15
Funziona solo se il minimo è 1. Se il minimo è 2 e usiamo ancora Math.floor(Math.random() * 6) + 2significa che se il Math.random()risultato è 0,99 il nostro valore casuale sarebbe7
antitossico

28
Questo codice non è buono perché, non funziona con nessun numero. Il codice @Francisc è corretto.
Lion King,

2287
function randomIntFromInterval(min, max) { // min and max included 
  return Math.floor(Math.random() * (max - min + 1) + min);
}

Ciò che fa "extra" è che consente intervalli casuali che non iniziano con 1. Quindi, ad esempio, puoi ottenere un numero casuale da 10 a 15. Flessibilità.


5
anche questo è fantastico perché se qualcuno non include l' toarg, l' fromarg raddoppia come il massimo
Jason

12
Ciao. Questo è da 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
Leggi il commento sopra. Casuale è all'interno di [0,1), non [0,1].
Francisc,

3
Funziona alla grande se il numero più basso è 0.
Robin Zimmermann,

2
Si noti che questa soluzione è corretta solo se min e max sono numeri interi, altrimenti è possibile ottenere un risultato nell'intervallo [min, ceil (max)]. Vale a dire che puoi ottenere un risultato fuori portata perché è superiore a max.
Collimarco,

329

Math.random ()

Restituisce un numero casuale intero compreso tra min ( incluso ) e max ( incluso ):

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

O qualsiasi numero casuale tra min ( incluso ) e max ( non incluso ):

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

Esempi utili (numeri interi):

// 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;

** E sempre bello da ricordare (Mozilla):

Math.random () non fornisce numeri casuali crittograficamente sicuri. Non utilizzarli per nulla relativi alla sicurezza. Utilizzare invece l'API Web Crypto e, più precisamente, il metodo window.crypto.getRandomValues ​​().


Qualcosa che mi ha confuso ... Math.floor (..) assicura che il numero sia un numero intero in cui Math.round (..) darebbe una distribuzione irregolare. Rif: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
alikuli

1
Mi fido di questa risposta. Qualcuno può dare un link o una chiara spiegazione del perché questo funziona? Forse un esempio di come Math.round darebbe un pregiudizio, e perché ciò significa che dobbiamo usare questa formula dall'aspetto piuttosto complesso?
Robin Andrews,

6
@alikuli Per una serie di [1,2], c'è il 25% di probabilità Math.random()darebbe un numero da uno di questi [0,0.49], [0.5,0.99], [1,1.49], [1.5,1.99]. Arrotondare quegli intervalli comporterebbe 0, 1, 1, 2 che non è una distribuzione uniforme. La loro pavimentazione risulta in 0, 0, 1, 1.
pishpish

1
@shuji Questa è , tra l'altro, la risposta corretta. Volevo solo chiarire perché l'uso di Math.roundover Math.flooravrebbe dato risultati diversi.
Pishpish,

La soluzione più accurata che ho trovato: function getRandomInt(min, max) { return Math.round((min - 0.5) + Math.random() * (max - min + 1)); }
Sadik

91

Altre soluzioni:

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

Prova online


6
ti dispiacerebbe spiegare (o dare riferimenti a) la ~~ sintassi? Non l'ho mai visto prima! Soluzione elegante ma difficile da capire.
DiegoDD,

27
Double Tilde ~~a e Bitwise OR (a | 0) sono modi più veloci per scrivere Math.floor (a)
edi9999

7
a | 0è anche il modo più veloce e ottimizzato per convertire una stringa in un numero intero. Funziona solo con stringhe contenenti numeri interi ( "444"e "-444"), cioè senza float / frazioni. Produce a 0per tutto ciò che fallisce. È una delle principali ottimizzazioni dietro asm.js.
pilau,

3
Nota: se lavori con numeri molto grandi, la doppia tilde non funzionerà. Prova ~~(Math.random() * (50000000000000 - 0 + 1)) + 0eMath.floor(Math.random() * (50000000000000 - 0 + 1)) + 0
BrunoLM,

3
"La doppia tilde e l'OR bit a bit / sono modi più veloci di scrivere il pavimento a punti matematici" è un bellissimo distico in rima che ha illuminato la mia mattinata. Grazie @ edi9999!
teedyay,

60

TL; DR

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

Per ottenere il numero casuale generateRandomInteger(-20, 20);

SPIEGAZIONE QUI SOTTO

Dobbiamo ottenere un numero intero casuale, diciamo X tra min e max.

Giusto?

cioè min <= X <= max

Se sottraggiamo min dall'equazione, questo equivale a

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

Ora, moltiplica questo per un numero casuale r che è

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

Ora, consente di aggiungere di nuovo min all'equazione

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

Ora, scegliamo una funzione che risulti in r tale da soddisfare la nostra gamma di equazioni come [min, max]. Questo è possibile solo se 0 <= r <= 1

OK. Ora, l'intervallo di r ie [0,1] è molto simile al risultato della funzione Math.random (). No?

La funzione Math.random () restituisce un numero pseudo-casuale in virgola mobile nell'intervallo [0, 1); cioè da 0 (incluso) fino a ma non incluso 1 (esclusivo)

Per esempio,

Caso r = 0

min+ 0 * ( max- min) = min

Caso r = 1

min+ 1 * ( max- min) = max

Caso casuale utilizzando Math.random 0 <= r <1

min+ r * ( max- min) = X , dove X ha un intervallo di min <= X < max

Il risultato sopra X è un numero casuale. Tuttavia, a causa di Math.random () il nostro limite sinistro è inclusivo e il limite destro è esclusivo. Per includere il limite destro, aumentiamo il limite destro di 1 e calcoliamo il risultato.

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

Per ottenere il numero casuale

generateRandomInteger(-20, 20);



24
var x = 6; // can be any number
var rand = Math.floor(Math.random()*x) + 1;

2
Infatti. Ho dimenticato rand era 0 compreso. Aggiustato.
ryebr3ad,

3
Fa parte dello Pseudocodice ... qualcuno potrebbe pensare che sia reale e provare a usarlo in quel modo.
Gravityboy,

35
@gravityboy Di cosa stai parlando? Se qualcuno non può sostituire un numero con [scegli un numero ...], potrebbe non essere adatto come programmatore.
ryebr3ad,

7
@ ryebr3ad -1! si dice in javascript non in pseudo codice e inoltre non tutti i lettori sono programmatori esperti. Molti sono principianti!
Steve,

3
@ ryebr3ad: ho avuto un collega che insegnava ai tirocinanti su un ambiente di database che avrebbero avuto bisogno di supporto. Ha detto loro di selezionare tutto da una tabella e hanno iniziato a scrivere "seleziona tutto da ..." proprio nell'editor di query SQL. Ha avuto la stessa reazione che hai fatto tu.
Ellesedil,

22

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

Intero casuale : per ottenere un numero intero casuale compreso tra mine max, utilizzare il seguente codice

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

Numero in virgola mobile casuale: per ottenere un numero in virgola mobile casuale tra mine max, utilizzare il seguente codice

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

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


14

La matematica non è il mio punto di forza, ma ho lavorato a un progetto in cui avevo bisogno di generare molti numeri casuali tra positivo e negativo.

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

Per esempio

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

Naturalmente, puoi anche aggiungere un po 'di validazione per assicurarti di non farlo con nient'altro che numeri. Assicurarsi inoltre che min sia sempre inferiore o uguale a max.


5
Questo è semplicemente sbagliato. min + Math.random() * maxti darà numeri tra min e min + max, che non è quello che desideri. Il primo ramo del ifè corretto, ma potrebbe essere semplificato per dire return min + Math.random() * (max - min), che è la soluzione corretta indipendentemente dal fatto che min sia positivo o negativo (vedi le altre risposte). Inoltre, tieni presente che devi ancora pavimentare il risultato se non vuoi frazioni.
Avish,

10

Ho scritto una funzione più flessibile che può darti un numero casuale ma non solo un numero intero.

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

Versione fissa.


Questa non è una buona soluzione in quanto non funzionerà con zero come valore minimo. Vedi la risposta di @ Lior.
Sebastien,

Ovviamente funziona con zero come valore minimo. Hai provato? Non c'è motivo per cui potrebbe non funzionare. Non funzionerà con 0 come intervallo che non è strano (intervallo = 0? ...).
ElChupacabra,

Ho eseguito più volte questa funzione con zero come valore minimo e non ho mai ottenuto zero nell'output. O non sono abbastanza fortunato ...
Sebastien,

Hai ragione. "+ intervallo" era nel posto sbagliato. Provalo ora per favore. Strana cosa che a volte console.log mi dà 0,300000004 invece di 0,3 come 3 * 0,1 non sarebbe esattamente 0,3.
ElChupacabra,

9

Esempio

Restituisce un numero casuale compreso tra 1 e 10:

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

Il risultato potrebbe essere: 3

Mettiti alla prova: qui

-

o usando lodash / undescore:

_.random(min, max)

Documenti: - lodash - undescore


1
quindi hai bisogno di 9 o 10 giusto? Se sì: const randomNumber = Math.floor ((Math.random () * 10) + 1) const nineOrTen = randomNumber% 2 === 0? 9: 10
Sebastián Lara,

7

Nonostante molte risposte e quasi lo stesso risultato. Vorrei aggiungere la mia risposta e spiegarne il funzionamento. Perché è importante capirne il funzionamento piuttosto che copiare incollando un codice di riga. Generare numeri casuali non è altro che semplici matematiche.

CODICE:

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));
}

6

Stavo cercando un generatore di numeri casuali scritto in TypeScript e ho scritto questo dopo aver letto tutte le risposte, spero che funzioni per i programmatori TypeScript.

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

5

Math.random() è veloce e adatto a molti scopi, ma non è appropriato se hai bisogno di valori crittograficamente sicuri (non è sicuro) o se hai bisogno di numeri interi da una distribuzione imparziale completamente uniforme (l'approccio di moltiplicazione utilizzato nelle altre risposte produce alcuni valori leggermente più spesso di altri).

In questi casi, possiamo usare crypto.getRandomValues()per generare numeri interi sicuri e rifiutare qualsiasi valore generato che non possiamo mappare uniformemente nell'intervallo target. Questo sarà più lento, ma non dovrebbe essere significativo se non stai generando un numero estremamente elevato di valori.

Per chiarire la preoccupazione di distribuzione distorta, considera il caso in cui vogliamo generare un valore compreso tra 1 e 5, ma abbiamo un generatore di numeri casuali che produce valori compresi tra 1 e 16 (un valore a 4 bit). Vogliamo avere lo stesso numero di valori generati associati a ciascun valore di output, ma 16 non si divide uniformemente per 5: lascia un resto di 1. Quindi dobbiamo rifiutare 1 dei possibili valori generati e continuare solo quando otteniamo uno dei 15 valori minori che possono essere uniformemente mappati nel nostro intervallo target. Il nostro comportamento potrebbe apparire come questo pseudocodice:

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.

Il codice seguente utilizza una logica simile, ma genera invece un numero intero a 32 bit, poiché si tratta della dimensione intera comune più grande che può essere rappresentata dal numbertipo standard di JavaScript . (Questo potrebbe essere modificato per usare BigInts se hai bisogno di un intervallo più ampio.) Indipendentemente dall'intervallo scelto, la frazione dei valori generati che vengono rifiutati sarà sempre inferiore a 0,5, quindi il numero atteso di rifiuti sarà sempre inferiore a 1,0 e di solito vicino a 0,0; non devi preoccuparti che rimanga in loop per sempre.

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]


Questo è ciò che chiamo eccessivo.
2x Samurai,

2
@ 2xSamurai Lì ho aggiornato la risposta per spiegare perché potresti averne bisogno e come funziona. Va meglio? : P
Jeremy Banks,

Non è affatto eccessivo se vuoi numeri casuali crittograficamente sicuri e distribuiti uniformemente. Generare numeri casuali che soddisfano tali requisiti è difficile. Ottima risposta, @JeremyBanks.
thomaskonrad il

4

Aggiunta floatcon versione a precisione fissa basata sulla intversione nella risposta di @ Francisc:

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

così:

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

e per la risposta int

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

3

Numero intero casuale cripto-forte nell'intervallo [a, b] (presupposto: a <b)

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

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


1

Questo dovrebbe funzionare:

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

1

Ho scoperto un nuovo fantastico modo per farlo usando i parametri predefiniti ES6. È molto intelligente poiché consente uno o due argomenti. Ecco qui:

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

1

Sono in ritardo di circa nove anni, ma randojs.com lo rende un semplice esempio:

rando(1, 6)

Devi solo aggiungere questo alla testa del tuo documento html e puoi fare praticamente tutto ciò che vuoi con casualità facilmente. Valori casuali da matrici, elementi jquery casuali, proprietà casuali dagli oggetti e persino prevenzione delle ripetizioni, se necessario.

<script src="https://randojs.com/1.0.0.js"></script>

Perché aggiungere una dipendenza per fare qualcosa che è già una linea? L'ossessione per l'aggiunta di librerie nella comunità JS è pazza
Daniel Cooke,

più facile da leggere e ricordare. sono d'accordo però
Aaron Plocharczyk il

1

Questo funziona per me e produce valori come la funzione di libreria standard random.randint di Python :


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

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

1

Prova a usare:

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


1

per restituire 1-6 come un dado fondamentalmente,

return Math.round(Math.random() * 5 + 1);
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.