2009-06-30 20 views
99

¿Es posible generar un número aleatorio entre 2 dobles?Número aleatorio entre 2 números dobles

Ejemplo:

public double GetRandomeNumber(double minimum, double maximum) 
{ 
    return Random.NextDouble(minimum, maximum) 
} 

Entonces me llaman con lo siguiente:

double result = GetRandomNumber(1.23, 5.34); 

serían apreciados Cualquier pensamiento.

Respuesta

241

Sí.

Random.NextDouble devuelve un doble entre 0 y 1. A continuación, multiplique eso por el rango que necesita ir (diferencia entre máximo y mínimo) y luego agréguelo a la base (mínimo).

public double GetRandomNumber(double minimum, double maximum) 
{ 
    Random random = new Random(); 
    return random.NextDouble() * (maximum - minimum) + minimum; 
} 

El código real debe tener al azar ser un miembro estático. Esto ahorrará el costo de crear el generador de números aleatorios y le permitirá llamar GetRandomNumber con mucha frecuencia. Como estamos inicializando un nuevo RNG con cada llamada, si llama lo suficientemente rápido como para que la hora del sistema no cambie entre llamadas, el RNG se sembrará con la misma marca de tiempo y generará el mismo flujo de números aleatorios.

+24

Sólo ten cuidado si se llama GetRandomNumber() en un bucle, ya que va a generar el mismo valor una y otra –

+0

@ John - Buen punto, añadí esto a mi respuesta. – Michael

+0

¡perfecto! Esto es lo que estaba buscando. Muchas gracias – CodeLikeBeaker

6

El enfoque más simple simplemente generaría un número aleatorio entre 0 y la diferencia de los dos números. Luego agregue el menor de los dos números al resultado.

3

Usted podría utilizar código como este:

public double getRandomNumber(double minimum, double maximum) { 
    return minimum + randomizer.nextDouble() * (maximum - minimum); 
} 
+2

¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡¡ha aparecido una var 'aleatoria mágica !! – Lucas

2

usted puede hacer esto:

public class RandomNumbers : Random 
{ 
    public RandomNumbers(int seed) : base(seed) { } 

    public double NextDouble(double minimum, double maximum) 
    { 
     return base.NextDouble() * (maximum - minimum) + minimum; 
    } 
} 
0

Sobre la generación del mismo número aleatorio si se llama en un bucle de una solución ingeniosa es declarar la nuevo objeto Random() fuera del bucle como variable global.

Observe que debe declarar su instancia de la clase Aleatoria fuera de la función GetRandomInt si va a ejecutar esto en un bucle.

"¿Por qué es esto?" Usted pregunta.

Bueno, la clase Aleatoria en realidad genera números pseudoaleatorios, con la "semilla" para el aleatorizador que es la hora del sistema. Si su ciclo es lo suficientemente rápido, la hora del reloj del sistema no aparecerá diferente al aleatorizador y cada nueva instancia de la clase Random comenzaría con la misma semilla y le dará el mismo número pseudo aleatorio.

Fuente está aquí: http://www.whypad.com/posts/csharp-get-a-random-number-between-x-and-y/412/

+0

Esto es más adecuado como comentario, ya que ni siquiera intenta responder a la pregunta real de OP. –

28

Johnny5 sugirió la creación de un método de extensión. Aquí está un ejemplo de código más completo que muestra cómo se puede hacer esto:

public static class RandomExtensions 
{ 
    public static double NextDouble(
     this Random random, 
     double minValue, 
     double maxValue) 
    { 
     return random.NextDouble() * (maxValue - minValue) + minValue; 
    } 
} 

ya se puede llamar como si se tratara de un método en la clase Random:

Random random = new Random(); 
double value = random.NextDouble(1.23, 5.34); 

Tenga en cuenta que no se debe crear un montón de nuevos objetos Random en un bucle porque esto hará que sea probable que obtenga el mismo valor muchas veces seguidas. Si necesita muchos números aleatorios, cree una instancia de Random y vuelva a utilizarla.

1

¿Qué sucede si uno de los valores es negativo? No sería una idea mejor ser:

double NextDouble(double min, double max) 
{ 
     if (min >= max) 
      throw new ArgumentOutOfRangeException();  
     return random.NextDouble() * (Math.Abs(max-min)) + min; 
} 
+0

Gracias por las ideas adicionales. Muy útil para una vieja pregunta :) – CodeLikeBeaker

+5

Creo que 'Math.Abs ​​()' es redundante. Como se aseguró de que 'min> = max', entonces' max - min' debe ser un número no negativo de todos modos. –

0
Random random = new Random(); 

double NextDouble(double minimum, double maximum) 
{ 

    return random.NextDouble()*random.Next(minimum,maximum); 

} 
4

Tenga cuidado: si se está generando la random dentro de un bucle como por ejemplo for(int i = 0; i < 10; i++), no ponga la declaración new Random() dentro del bucle.

De MSDN:

Las aleatorios de generación de números comienza a partir de un valor de semilla. Si se usa la misma semilla repetidamente, se genera la misma serie de números. Una forma de producir secuencias diferentes es hacer que el valor inicial dependa del tiempo, produciendo así una serie diferente con cada instancia nueva de de Random. Por defecto, el constructor sin parámetros de la clase Random utiliza el reloj del sistema para generar su valor semilla ...

Así que basado en este hecho, hacer algo como:

var random = new Random(); 

for(int d = 0; d < 7; d++) 
{ 
    // Actual BOE 
    boes.Add(new LogBOEViewModel() 
    { 
     LogDate = criteriaDate, 
     BOEActual = GetRandomDouble(random, 100, 1000), 
     BOEForecast = GetRandomDouble(random, 100, 1000) 
    }); 
} 

double GetRandomDouble(Random random, double min, double max) 
{ 
    return min + (random.NextDouble() * (max - min)); 
} 

Haciendo de esta manera usted tenga la garantía de que obtendrá diferentes valores dobles.

0

Si necesita un número aleatorio en el rango [double.MinValue; double.MaxValue]

// Because of: 
double.MaxValue - double.MinValue == double.PositiveInfinity 

// This will be equals to NaN or PositiveInfinity 
random.NextDouble() * (double.MaxValue - double.MinValue) 

usar en su lugar:

public static class RandomExtensions 
{ 
    public static double NextDoubleInMinMaxRange(this Random random) 
    { 
     var bytes = new byte[sizeof(double)]; 
     var value = default(double); 
     while (true) 
     { 
      random.NextBytes(bytes); 
      value = BitConverter.ToDouble(bytes, 0); 
      if (!double.IsNaN(value) && !double.IsInfinity(value)) 
       return value; 
     } 
    } 
} 
+1

Buen punto, pero esta proposición da como resultado una distribución sesgada como en el segundo ejemplo aquí https://stackoverflow.com/a/3365388/3922292 –

Cuestiones relacionadas