Si.
Random.NextDouble devuelve un doble entre 0 y 1. Luego lo multiplica por el rango que necesita ingresar (diferencia entre máximo y mínimo) y luego agrega eso 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 a 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á la misma secuencia de números aleatorios.
public double GetRandomNumber(this Random random, double minimum, double maximum) {...}
Johnny5 sugirió crear un método de extensión. Aquí hay un ejemplo de código más completo que muestra cómo podría hacer esto:
Ahora puede llamarlo como si fuera un método en la
Random
clase:Tenga en cuenta que no debe crear muchos
Random
objetos nuevos 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 instanciaRandom
y reutilícela.fuente
Cuidado: si estás generando el
random
interior de un ciclo como, por ejemplofor(int i = 0; i < 10; i++)
, no pongas elnew Random()
declaración dentro del ciclo.De MSDN :
Entonces, en base a este hecho, haga algo como:
Al hacerlo, tiene la garantía de que obtendrá diferentes valores dobles.
fuente
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.
fuente
Podrías usar un código como este:
fuente
Podrías hacer esto:
fuente
Llegué un poco tarde a la fiesta, pero necesitaba implementar una solución general y resultó que ninguna de las soluciones puede satisfacer mis necesidades.
La solución aceptada es buena para rangos pequeños; sin embargo,
maximum - minimum
puede ser infinito para grandes rangos. Entonces una versión corregida puede ser esta versión:Esto genera números aleatorios muy bien incluso entre
double.MinValue
ydouble.MaxValue
. Pero esto introduce otro "problema", que se presenta muy bien en esta publicación : si usamos rangos tan grandes, los valores pueden parecer demasiado "antinaturales". Por ejemplo, después de generar 10,000 dobles al azar entre 0 ydouble.MaxValue
todos los valores estaban entre 2.9579E + 304 y 1.7976E + 308.Así que creé también otra versión, que genera números en una escala logarítmica:
Algunas pruebas:
Aquí están los resultados ordenados de generar 10,000 números dobles aleatorios entre 0 y
Double.MaxValue
con ambas estrategias. Los resultados se muestran usando la escala logarítmica:Aunque los valores aleatorios lineales parecen estar equivocados a primera vista, las estadísticas muestran que ninguno de ellos es "mejor" que el otro: incluso la estrategia lineal tiene una distribución uniforme y la diferencia promedio entre los valores es prácticamente la misma con ambas estrategias. .
Jugar con diferentes rangos me mostró que la estrategia lineal llega a ser "sana" con un rango entre 0 y
ushort.MaxValue
con un valor mínimo "razonable" de 10.78294704 (para elulong
rango, el valor mínimo era 3.03518E + 15int
;: 353341). Estos son los mismos resultados de ambas estrategias que se muestran con diferentes escalas:Editar:
Recientemente hice mis bibliotecas de código abierto, siéntase libre de ver el
RandomExtensions.NextDouble
método con la validación completa.fuente
¿Qué pasa si uno de los valores es negativo? No sería una mejor idea:
fuente
Math.Abs()
es redundante. Como se aseguró esomin >= max
,max - min
debe ser un número no negativo de todos modos.Si necesita un número aleatorio en el rango [
double.MinValue
;double.MaxValue
]Use en su lugar:
fuente
Acerca de generar el mismo número aleatorio si lo llama en un bucle, una solución ingeniosa es declarar el nuevo objeto Random () fuera del bucle como una variable global.
Tenga en cuenta que debe declarar su instancia de la clase Random fuera de la función GetRandomInt si va a ejecutar esto en un bucle.
"¿Por qué es esto?" usted pregunta.
Bueno, la clase Random en realidad genera números pseudoaleatorios, siendo la "semilla" para el aleatorizador la hora del sistema. Si su ciclo es suficientemente rápido, la hora del reloj del sistema no aparecerá diferente al aleatorizador y cada nueva instancia de la clase Aleatoria comenzaría con la misma semilla y le daría el mismo número pseudoaleatorio.
La fuente está aquí: http://www.whypad.com/posts/csharp-get-a-random-number-between-x-and-y/412/
fuente
Use un Random estático o los números tienden a repetirse en bucles apretados / rápidos debido a que el reloj del sistema los envía.
Ver también: https://docs.microsoft.com/en-us/dotnet/api/system.random?view=netframework-4.8
fuente
fuente