Generar números aleatorios entre dos números en JavaScript

1798

¿Hay alguna manera de generar un número aleatorio en un rango específico (por ejemplo, de 1 a 6: 1, 2, 3, 4, 5 o 6) en JavaScript?

Mirgorod
fuente
12
Math.floor (Math.random () * 7)
Amjad Masad
65
Claro .. Math.floor (Math.random () * 6 + 1)
Amjad Masad
3
Nabil Kadimi escribió un artículo sobre cómo generar números aleatorios negativos también.
madc
Aquí hay un resumen
Dan KK
¿Por qué una solución como esta Math.floor((Math.random()*10)+1);no puede funcionar para usted como se especifica aquí en w3schools.com/jsref/jsref_random.asp ..?
shashwat

Respuestas:

2118

Importante

El siguiente código funciona solo si el valor mínimo es 1. No funciona para valores mínimos que no sean 1.

Si desea obtener un número entero aleatorio entre 1 ( y solo 1 ) y 6, calcularía:

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

Dónde:

  • 1 es el número de inicio
  • 6 es el número de resultados posibles (1 + inicio (6) - final (1) )
khr055
fuente
45
Si bien esto funcionaría, @Mike, sería mejor señalar la versión más genérica, ya que Francisc la tiene a continuación :-).
Raymond Machira
59
-1. Después de buscar en Google encontré esta pregunta, el título es "" Generar valor aleatorio entre dos números en Javascript "". No funcionará si el valor mínimo es 0
Ydhem
18
No funciona si desea un número entre dos números más grandes, por ejemplo. Math.floor (Math.random () * 900) + 700
Rob el
15
Eso sólo funciona si el mínimo es 1. Si el min es 2 y aún usamos Math.floor(Math.random() * 6) + 2significa que si Math.random()los resultados en nuestra 0.99 valor aleatorio serían7
antitoxic
28
Este código no es bueno porque no funciona con ningún número. El código de @Francisc es el correcto.
Rey León
2289
function randomIntFromInterval(min, max) { // min and max included 
  return Math.floor(Math.random() * (max - min + 1) + min);
}

Lo que hace "extra" es que permite intervalos aleatorios que no comienzan con 1. Por lo tanto, puede obtener un número aleatorio del 10 al 15, por ejemplo. Flexibilidad.

Francisc
fuente
55
esto también es genial porque si alguien no incluye el toargumento, el fromargumento se dobla como máximo
Jason
12
Hola. Esto es de 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
55
Lee el comentario anterior. Aleatorio está dentro de [0,1), no [0,1].
Francisc
3
Funciona muy bien si el número más bajo es 0.
Robin Zimmermann
2
Tenga en cuenta que esta solución es correcta solo si min y max son enteros; de lo contrario, puede obtener un resultado en el intervalo [min, ceil (max)]. Es decir, puede obtener un resultado que está fuera de rango porque es superior al máximo.
collimarco
329

Math.random ()

Devuelve un número aleatorio entero entre min ( incluido ) y max ( incluido ):

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

O cualquier número aleatorio entre min ( incluido ) y max ( no incluido ):

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

Ejemplos útiles (enteros):

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

** Y siempre es bueno recordarlo (Mozilla):

Math.random () no proporciona números aleatorios criptográficamente seguros. No los use para nada relacionado con la seguridad. Utilice la API de cifrado web en su lugar y, más precisamente, el método window.crypto.getRandomValues ​​().

Lior Elrom
fuente
Algo que me confundió ... el Math.floor (..) asegura que el número sea un número entero donde Math.round (..) daría una distribución desigual. Ref: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
alikuli
1
Confío en esta respuesta. ¿Alguien puede dar un enlace o una explicación clara de por qué esto funciona? Quizás un ejemplo de cómo Math.round daría un sesgo, y ¿por qué eso significa que tenemos que usar esta fórmula bastante compleja?
Robin Andrews
66
@alikuli Para una gama de [1,2], hay 25% de posibilidades Math.random()que le dará un número de uno de éstos [0,0.49], [0.5,0.99], [1,1.49], [1.5,1.99]. Redondear esos intervalos daría como resultado 0, 1, 1, 2, que no es una distribución uniforme.
Su
1
@shuji Esta es , entre otras, la respuesta correcta. Solo quería aclarar por qué usar Math.roundover Math.floordaría resultados diferentes.
pishpish
La solución más precisa que he encontrado: function getRandomInt(min, max) { return Math.round((min - 0.5) + Math.random() * (max - min + 1)); }
Sadik
91

Otras soluciones:

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

Probar en línea

Vishal
fuente
66
¿te importaría explicar (o dar referencias a) la sintaxis ~~? ¡No lo he visto antes! Solución elegante pero difícil de entender.
DiegoDD
27
Double Tilde ~~a y Bitwise OR (a | 0) son formas más rápidas de escribir Math.floor (a)
edi9999
77
a | 0es también la forma más rápida y optimizada de convertir una cadena en un entero. Solo funciona con cadenas que contienen enteros ( "444"y "-444"), es decir, sin flotantes / fracciones. Produce un 0por todo lo que falla. Es una de las principales optimizaciones detrás de asm.js.
pilau
3
Nota: si está trabajando con algunos números realmente grandes, la doble tilde no funcionará. Prueba ~~(Math.random() * (50000000000000 - 0 + 1)) + 0yMath.floor(Math.random() * (50000000000000 - 0 + 1)) + 0
BrunoLM
3
"Doble tilde y bit / OR / son formas más rápidas de escribir Math dot floor" es un hermoso pareado que rima mi mañana. Gracias @ edi9999!
teedyay
60

TL; DR

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

Para obtener el número aleatorio generateRandomInteger(-20, 20);

EXPLICACIÓN A CONTINUACIÓN

Necesitamos obtener un número entero aleatorio, digamos X entre min y max.

¿Derecha?

es decir, min <= X <= max

Si restamos min de la ecuación, esto es equivalente a

0 <= (X - min) <= (máx - min)

Ahora, multipliquemos esto con un número aleatorio r que es

0 <= (X - min) * r <= (máx - min) * r

Ahora, agreguemos de nuevo min a la ecuación

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

Ahora, elija una función que resulte en r de manera que satisfaga nuestro rango de ecuaciones como [min, max]. Esto solo es posible si 0 <= r <= 1

OKAY. Ahora, el rango de r, es decir, [0,1] es muy similar al resultado de la función Math.random (). ¿No es así?

La función Math.random () devuelve un número pseudoaleatorio de punto flotante en el rango [0, 1); es decir, desde 0 (inclusive) hasta pero sin incluir 1 (exclusivo)

Por ejemplo,

Caso r = 0

min+ 0 * ( max- min) = min

Caso r = 1

min+ 1 * ( max- min) = máx.

Caso aleatorio usando Math.random 0 <= r <1

min+ r * ( max- min) = X , donde X tiene un rango de min <= X < max

El resultado anterior X es un número aleatorio. Sin embargo, debido a Math.random () nuestro límite izquierdo es inclusivo, y el límite derecho es exclusivo. Para incluir nuestro límite derecho, aumentamos el límite derecho en 1 y subimos el resultado.

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

Para obtener el número aleatorio

generateRandomInteger(-20, 20);

Faiz Mohamed Haneef
fuente
24
var x = 6; // can be any number
var rand = Math.floor(Math.random()*x) + 1;
ryebr3ad
fuente
2
En efecto. Olvidé que rand era 0 inclusive. Arreglado.
ryebr3ad
3
Eso es parte del pseudocódigo ... alguien podría pensar que es real e intentar usarlo así.
gravityboy
35
@gravityboy ¿De qué estás hablando? Si alguien no puede sustituir un número por [elegir un número ...], puede que no sea adecuado como programador.
ryebr3ad
77
@ ryebr3ad -1! se dice en javascript, no en pseudocódigo y tampoco todos los lectores son programadores consumados. ¡Muchos son principiantes!
Steve
3
@ ryebr3ad: he tenido un compañero de trabajo que estaba enseñando a los pasantes sobre un entorno de base de datos que necesitarían apoyo. Les dijo que seleccionaran todo de una tabla y comenzaron a escribir "seleccionar todo de ..." directamente en el editor de consultas SQL. Tuvo la misma reacción que tú.
Ellesedil
22

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

Entero aleatorio : para obtener un entero aleatorio entre miny max, use el siguiente código

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

Número aleatorio de coma flotante : para obtener un número aleatorio de coma flotante entre miny max, use el siguiente código

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

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

Razan Paul
fuente
14

Las matemáticas no son mi punto fuerte, pero he estado trabajando en un proyecto donde necesitaba generar muchos números aleatorios entre positivos y negativos.

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

P.ej

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

Por supuesto, también puede agregar alguna validación para asegurarse de no hacer esto con otra cosa que no sean números. También asegúrese de que min siempre sea menor o igual que max.

Petter Thowsen
fuente
55
Esto simplemente está mal. min + Math.random() * maxle dará números entre min y min + max, que no es lo que desea. La primera rama de la ifes correcta, pero podría simplificarse para decir return min + Math.random() * (max - min)cuál es la solución correcta independientemente de si min es positivo o negativo (ver las otras respuestas). Además, tenga en cuenta que aún necesita anotar el resultado si no desea fracciones.
Avish
10

Escribí una función más flexible que puede darte un número aleatorio pero no solo un entero.

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

Versión fija

ElChupacabra
fuente
Esta no es una buena solución, ya que no funcionará con cero como valor mínimo. Ver la respuesta de @ Lior.
Sebastien
Por supuesto, funciona con cero como valor mínimo. ¿Has probado? No hay razón para que no funcione. No funcionará con 0 como intervalo, lo cual no es extraño (intervalo = 0? ...).
ElChupacabra
Ejecuté varias veces esta función con cero como valor mínimo y nunca obtuve cero en la salida. O no tengo la suerte ...
Sebastien
Tienes razón. "+ intervalo" estaba en el lugar equivocado. Pruébalo ahora por favor. Lo extraño que a veces console.log me da 0.300000004 en lugar de 0.3 como 3 * 0.1 no sería exactamente 0.3.
ElChupacabra
9

Ejemplo

Devuelve un número aleatorio entre 1 y 10:

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

El resultado podría ser: 3

Pruébalo tú mismo: aquí

-

o usando lodash / undescore:

_.random(min, max)

Documentos: - lodash - undescore

Sebastián Lara
fuente
1
entonces necesitas 9 o 10 ¿verdad? En caso afirmativo: const randomNumber = Math.floor ((Math.random () * 10) + 1) const nineOrTen = randomNumber% 2 === 0? 9: 10
Sebastián Lara
7

A pesar de muchas respuestas y casi el mismo resultado. Me gustaría agregar mi respuesta y explicar su funcionamiento. Porque es importante comprender su funcionamiento en lugar de copiar y pegar un código de línea. Generar números aleatorios no es más que simples matemáticas.

CÓDIGO:

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
fuente
6

Estaba buscando un generador de números aleatorios escrito en TypeScript y lo he escrito después de leer todas las respuestas, espero que funcione para los codificadores de TypeScript.

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

Math.random() es rápido y adecuado para muchos propósitos, pero no es apropiado si necesita valores criptográficamente seguros (no es seguro) o si necesita números enteros de una distribución imparcial completamente uniforme (el enfoque de multiplicación utilizado en otras respuestas produce ciertos valores un poco más a menudo que otros).

En tales casos, podemos usar crypto.getRandomValues()para generar enteros seguros y rechazar cualquier valor generado que no podamos asignar de manera uniforme en el rango objetivo. Esto será más lento, pero no debería ser significativo a menos que esté generando cantidades extremadamente grandes de valores.

Para aclarar el problema de la distribución sesgada, considere el caso en el que queremos generar un valor entre 1 y 5, pero tenemos un generador de números aleatorios que produce valores entre 1 y 16 (un valor de 4 bits). Queremos tener el mismo número de valores generados que se asignen a cada valor de salida, pero 16 no se divide equitativamente por 5: deja un resto de 1. Por lo tanto, debemos rechazar 1 de los posibles valores generados, y solo continuar cuando obtengamos uno de los 15 valores menores que se pueden mapear uniformemente en nuestro rango objetivo. Nuestro comportamiento podría parecerse a este pseudocódigo:

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.

El siguiente código utiliza una lógica similar, pero en su lugar genera un número entero de 32 bits, porque ese es el tamaño entero común más grande que puede ser representado por el numbertipo estándar de JavaScript . (Esto podría modificarse para usar BigInts si necesita un rango mayor). Independientemente del rango elegido, la fracción de valores generados que se rechazan siempre será menor que 0.5, por lo que el número esperado de rechazos siempre será menor que 1.0 y usualmente cerca de 0.0; no necesita preocuparse por que se repita para siempre.

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
fuente
Ahora, esto es lo que yo llamo exageración.
2xSamurai
2
@ 2xSamurai Allí, actualicé la respuesta para explicar por qué podría necesitar esto y cómo funciona. ¿Eso está mejor? : P
Jeremy Banks
No es una exageración en absoluto si quieres números aleatorios criptográficamente seguros y distribuidos uniformemente. Generar números aleatorios que cumplan esos requisitos es difícil. Gran respuesta, @JeremyBanks.
thomaskonrad
4

Agregando floatcon una versión de precisión fija basada en la intversión en la respuesta de @ Francisc:

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

entonces:

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

y para int respuesta

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

Número entero aleatorio cripto-fuerte en el rango [a, b] (suposición: 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
fuente
1

Esto debería funcionar:

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

Descubrí una nueva forma de hacer esto usando los parámetros predeterminados de ES6. Es muy ingenioso ya que permite un argumento o dos argumentos. Aquí está:

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

Esto lleva unos nueve años de retraso, pero randojs.com lo convierte en una frase simple:

rando(1, 6)

Solo necesita agregar esto al encabezado de su documento html, y puede hacer casi lo que quiera con aleatoriedad fácilmente. Valores aleatorios de matrices, elementos jquery aleatorios, propiedades aleatorias de objetos e incluso evitar repeticiones si es necesario.

<script src="https://randojs.com/1.0.0.js"></script>
Aaron Plocharczyk
fuente
¿Por qué agregar una dependencia para hacer algo que ya es una línea? La obsesión por agregar bibliotecas en la comunidad JS es una locura
Daniel Cooke
Más fácil de leer y recordar. aunque estoy de acuerdo
Aaron Plocharczyk
1

Esto funciona para mí y produce valores como la función de biblioteca estándar random.randint de Python :


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

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

Intenta usar:

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

AyushKatiyar
fuente
1

para devolver 1-6 como un dado básicamente,

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