What is the best way to generate a random float in C#?
Update: I want random floating point numbers from float.Minvalue to float.Maxvalue. I am using these numbers in unit testing of some mathematical methods.
This question is related to
c#
random
floating-point
I prefer using the following code to generate a decimal number up to fist decimal point. you can copy paste the 3rd line to add more numbers after decimal point by appending that number in string "combined". You can set the minimum and maximum value by changing the 0 and 9 to your preferred value.
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);
I hope that it helped you.
Another solution is to do this:
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;
}
Here is another way that I came up with: Let's say you want to get a float between 5.5 and 7, with 3 decimals.
float myFloat;
int myInt;
System.Random rnd = new System.Random();
void GenerateFloat()
{
myInt = rnd.Next(1, 2000);
myFloat = (myInt / 1000) + 5.5f;
}
That way you will always get a bigger number than 5.5 and a smaller number than 7.
I took a slightly different approach than others
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;
}
The comments explain what I'm doing. Get the next double, convert that number to a value between -1 and 1 and then multiply that with float.MaxValue
.
One more version... (I think this one is pretty good)
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));
I think this...
And One more version...(not as good but posting anyway)
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));
I think this...
Testing of most of the functions on this page: (i7, release, without debug, 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
Any reason not to use Random.NextDouble
and then cast to float
? That will give you a float between 0 and 1.
If you want a different form of "best" you'll need to specify your requirements. Note that Random
shouldn't be used for sensitive matters such as finance or security - and you should generally reuse an existing instance throughout your application, or one per thread (as Random
isn't thread-safe).
EDIT: As suggested in comments, to convert this to a range of 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;
EDIT: Now you've mentioned that this is for unit testing, I'm not sure it's an ideal approach. You should probably test with concrete values instead - making sure you test with samples in each of the relevant categories - infinities, NaNs, denormal numbers, very large numbers, zero, etc.
Source: Stackoverflow.com