Math.random () explicación

133

Esta es una pregunta bastante simple de Java (aunque probablemente aplicable a toda la programación):

Math.random() devuelve un número entre cero y uno.

Si quiero devolver un número entero entre cero y cien, haría:

(int) Math.floor(Math.random() * 101)

Entre uno y cien, haría:

(int) Math.ceil(Math.random() * 100)

Pero, ¿y si quisiera obtener un número entre tres y cinco? Será como la siguiente declaración:

(int) Math.random() * 5 + 3

Sé sobre nextInt()en java.lang.util.Random. Pero quiero aprender cómo hacer esto Math.random().

Switz
fuente
Para [3,5]:(int)Math.floor(Math.random()*3) + 3
good_evening el
9
Por cierto: el rango es de 0.0 inclusive a 1.0 exclusivo (nunca obtendrá 1.0 nunca) Usar nextInt () es una opción mucho mejor, no solo es más simple sino también mucho más rápido.
Peter Lawrey el
2
Usar Math.ceiles incorrecto, da el resultado incorrecto cuando Math.random()regresa 0.
Starblue
¿Qué pasa si Math.floor devuelve 0.029? ¿Cómo obtener siempre un número de dos dígitos con una sola declaración?
Naisheel Verdhan

Respuestas:

165
int randomWithRange(int min, int max)
{
   int range = (max - min) + 1;     
   return (int)(Math.random() * range) + min;
}

Salida de randomWithRange(2, 5)10 veces:

5
2
3
3
2
4
4
4
5
4

Los límites son inclusivos, es decir, [2,5], y mindeben ser menores que maxen el ejemplo anterior.

EDITAR: si alguien intentara ser estúpido y revertir miny max, podría cambiar el código a:

int randomWithRange(int min, int max)
{
   int range = Math.abs(max - min) + 1;     
   return (int)(Math.random() * range) + (min <= max ? min : max);
}

EDIT2: Para su pregunta sobre doubles, es solo:

double randomWithRange(double min, double max)
{
   double range = (max - min);     
   return (Math.random() * range) + min;
}

Y de nuevo, si quieres probarlo como un idiota, es solo:

double randomWithRange(double min, double max)
{
   double range = Math.abs(max - min);     
   return (Math.random() * range) + (min <= max ? min : max);
}
AusCBloke
fuente
1
¿Qué pasa si no usa (int)y desea que devuelva un double?
Switz
Si desea el doble, simplemente reemplace la ints con doubles (y la conversión de tipos es innecesaria). Asumí que querías ints pero agregaré a mi publicación.
AusCBloke
2
En realidad, con doubles eliminar el + 1también ya Math.random()que no se está truncando. Sin embargo, el rango será [min, max) ya que Math.random"Devuelve un valor doble con un signo positivo, mayor o igual que 0.0 y menor que 1.0". Existiría una posibilidad mínima de que el número sea exactamente maxigual, incluso si fuera posible.
AusCBloke
44

Si desea generar un número del 0 al 100, su código se vería así:

(int)(Math.random() * 101);

Para generar un número del 10 al 20:

(int)(Math.random() * 11 + 10);

En el caso general:

(int)(Math.random() * ((upperbound - lowerbound) + 1) + lowerbound);

(donde lowerboundes inclusivo y upperboundexclusivo).

La inclusión o exclusión de upperbounddepende de su elección. Digamos range = (upperbound - lowerbound) + 1entonces upperboundes inclusiva, pero si range = (upperbound - lowerbound)a continuación upperboundes exclusivo.

Ejemplo: si quiero un número entero entre 3-5, entonces si el rango es (5-3) +1, entonces 5 es inclusivo, pero si el rango es solo (5-3), entonces 5 es exclusivo.

Teezy7
fuente
2
upperbound¿exclusivo? Creo que será inclusivo.
vidit
1
@vidit es exclusivo
1
no creas que estás obteniendo el panorama general que puede ser superior, como se
indica
19

La Randomclase de Java ubicada en el java.utilpaquete servirá mejor a su propósito. Tiene algunos nextInt()métodos que devuelven un número entero. El que toma un argumento int generará un número entre 0 y ese int, el último no incluyente.

G_H
fuente
Actualicé mi pregunta, me gustaría saber cómo hacerlo Math.random(). Gracias.
Switz
1

Para generar un número entre 10 y 20 inclusive, puede usar java.util.Random

int myNumber = new Random().nextInt(11) + 10
Ilya Gazman
fuente
0

Aquí hay un método que recibe límites y devuelve un entero aleatorio. Es un poco más avanzado (completamente universal): los límites pueden ser tanto positivos como negativos , y los límites mínimos / máximos pueden venir en cualquier orden.

int myRand(int i_from, int i_to) {
  return (int)(Math.random() * (Math.abs(i_from - i_to) + 1)) + Math.min(i_from, i_to);
}

En general, encuentra la distancia absoluta entre los bordes, obtiene un valor aleatorio relevante y luego cambia la respuesta según el borde inferior.

tolerante a fallos
fuente