semilla repetir propiedad nĂºmero numeros hacer generar decimales con como arreglo aleatorios aleatorio c# random floating-point

repetir - La mejor forma de generar un flotante aleatorio en C#



propiedad random c# (7)

¿Alguna razón para no usar Random.NextDouble y luego lanzar para float ? Eso te dará un flotador entre 0 y 1.

Si desea una forma diferente de "mejor", deberá especificar sus requisitos. Tenga en cuenta que Random no se debe usar para asuntos delicados, como finanzas o seguridad, y generalmente debe reutilizar una instancia existente en su aplicación, o una por hilo (ya que Random no es seguro para subprocesos).

EDITAR: Como se sugiere en los comentarios, para convertir esto a un rango de float.MinValue , float.MaxValue :

// Perform arithmetic in double type to avoid overflowing double range = (double) float.MaxValue - (double) float.MinValue; double sample = rng.NextDouble(); double scaled = (sample * range) + float.MinValue; float f = (float) scaled;

EDITAR: Ahora que has mencionado que esto es para pruebas unitarias, no estoy seguro de que sea un enfoque ideal. Probablemente debería probar con valores concretos en su lugar, asegurándose de probar con muestras en cada una de las categorías relevantes: infinitos, NaN, números denormales, números muy grandes, cero, etc.

¿Cuál es la mejor forma de generar un flotante aleatorio en C #?

Actualización: Quiero números de coma flotante aleatorios de float.Minvalue a float.Maxvalue. Estoy usando estos números en pruebas unitarias de algunos métodos matemáticos.


Aquí hay otra manera en la que se me ocurrió: digamos que quieres obtener una flotación entre 5.5 y 7, con 3 decimales.

float myFloat; int myInt; System.Random rnd = new System.Random(); void GenerateFloat() { myInt = rnd.Next(1, 2000); myFloat = (myInt / 1000) + 5.5f; }

De esa forma siempre obtendrás un número mayor que 5.5 y un número menor que 7.


El mejor enfoque, sin valores enloquecidos, distribuido con respecto a los intervalos representables en la línea numérica de coma flotante (eliminado "uniforme" como con respecto a una línea numérica continua, es decididamente no uniforme):

static float NextFloat(Random random) { double mantissa = (random.NextDouble() * 2.0) - 1.0; double exponent = Math.Pow(2.0, random.Next(-126, 128)); return (float)(mantissa * exponent); }

Otro enfoque que le dará algunos valores enloquecidos (distribución uniforme de patrones de bits), potencialmente útil para el fuzzing:

static float NextFloat(Random random) { var buffer = new byte[4]; random.NextBytes(buffer); return BitConverter.ToSingle(buffer,0); }

Enfoque menos útil:

static float NextFloat(Random random) { // Not a uniform distribution w.r.t. the binary floating-point number line // which makes sense given that NextDouble is uniform from 0.0 to 1.0. // Uniform w.r.t. a continuous number line. // // The range produced by this method is 6.8e38. // // Therefore if NextDouble produces values in the range of 0.0 to 0.1 // 10% of the time, we will only produce numbers less than 1e38 about // 10% of the time, which does not make sense. var result = (random.NextDouble() * (Single.MaxValue - (double)Single.MinValue)) + Single.MinValue; return (float)result; }

Número de punto flotante de: Intel Architecture Software Manual del desarrollador Volumen 1: Arquitectura básica. El eje Y es logarítmico (base-2) porque los números de coma flotante binarios consecutivos no difieren linealmente.


Otra solución es hacer esto:

static float NextFloat(Random random) { float f; do { byte[] bytes = new byte[4]; random.NextBytes(bytes); f = BitConverter.ToSingle(bytes, 0); } while (float.IsInfinity(f) || float.IsNaN(f)); return f; }


Prefiero usar el siguiente código para generar un número decimal hasta el punto decimal del puño. puede copiar pegar la 3ra línea para agregar más números después del punto decimal al agregar ese número en la cadena "combinada". Puede establecer el valor mínimo y máximo cambiando el 0 y 9 a su valor preferido.

Random r = new Random(); string beforePoint = r.Next(0, 9).ToString();//number before decimal point string afterPoint = r.Next(0,9).ToString();//1st decimal point //string secondDP = r.Next(0, 9).ToString();//2nd decimal point string combined = beforePoint+"."+afterPoint; decimalNumber= float.Parse(combined); Console.WriteLine(decimalNumber);

Espero que te haya ayudado.


Tomé un enfoque un poco diferente que otros

static float NextFloat(Random random) { double val = random.NextDouble(); // range 0.0 to 1.0 val -= 0.5; // expected range now -0.5 to +0.5 val *= 2; // expected range now -1.0 to +1.0 return float.MaxValue * (float)val; }

Los comentarios explican lo que estoy haciendo. Obtenga el siguiente doble, convierta ese número a un valor entre -1 y 1 y luego multiplique eso con float.MaxValue .


Una versión más ... (Creo que esta es bastante buena)

static float NextFloat(Random random) { (float)(float.MaxValue * 2.0 * (rand.NextDouble()-0.5)); } //inline version float myVal = (float)(float.MaxValue * 2.0 * (rand.NextDouble()-0.5));

Pienso esto...

  • es el segundo más rápido (ver puntos de referencia)
  • está distribuido uniformemente

Y una versión más ... (no tan buena, pero publicar de todos modos)

static float NextFloat(Random random) { return float.MaxValue * ((rand.Next() / 1073741824.0f) - 1.0f); } //inline version float myVal = (float.MaxValue * ((rand.Next() / 1073741824.0f) - 1.0f));

Pienso esto...

  • es el más rápido (ver puntos de referencia)
  • Sin embargo, se distribuye de manera uniforme porque Next () es un valor aleatorio de 31 bits; solo devolverá 2 ^ 31 valores. (50% de los valores vecinos tendrán el mismo valor)

Prueba de la mayoría de las funciones en esta página: (i7, versión, sin depurar, 2 ^ 28 loops)

Sunsetquest1: min: 3.402823E+38 max: -3.402823E+38 time: 3096ms SimonMourier: min: 3.402823E+38 max: -3.402819E+38 time: 14473ms AnthonyPegram:min: 3.402823E+38 max: -3.402823E+38 time: 3191ms JonSkeet: min: 3.402823E+38 max: -3.402823E+38 time: 3186ms Sixlettervar: min: 1.701405E+38 max: -1.701410E+38 time: 19653ms Sunsetquest2: min: 3.402823E+38 max: -3.402823E+38 time: 2930ms