- Home /
How Precise is Random.Range?
If I use Random.Range (0f, 1f), how precise is it? Or how many different values can it return? How many decimal places does it go out to?
And, is it dependent on the number of decimal places I use in my min and max values?
Edit: And does it change based on the size of the range? Does a range of (0f, 100f) have more or the same number of possible return values than the previous situation?
Answer by tanoshimi · Jan 17, 2017 at 08:36 AM
Random.Range returns a floating point value, so the concept of decimal places doesn't really apply.
In terms of the range of possible values, a single-precision float is 32bit and each of those bits can be 1 or 0. So that's 2^32 different values that it can represent = 4,294,967,296. Now by asking only for output within a given range you won't get that many unique outcomes because you're applying a constraint on the exponent, but you should get enough variety for almost all game applications.
So would 1/4294967296 for the first one give the first possible value, with all others being multiples of that? And 100/4294967296 for the second one? Or am I understanding it incorrectly?
Additionally, you say that one won't get many unique outcomes...shouldn't it it be random, regardless?
You have to understand how floating point numbers work (at least a little bit) to understand the answer. It's not that straight forward...
"Floating point" means that the position of the decimal point...wait for it... "floats". With bigger numbers you have less decimal precision since the large whole number part takes up more bits.
Additionally, you say that one won't get many unique outcomes...shouldn't it it be random, regardless?
@tanoshimi said
Now by asking only for output within a given range you won't get that many unique outcomes
A range of 0 to 1 has fewer possible random unique bit combinations than the whole range of float.$$anonymous$$inValue
to float.$$anonymous$$axValue
which contains all of the possible combinations.
I like to think of floats the same way I think about scientific notation, like 5.234E-4= 5.23x10^-4
Though obviously it's is all base-2, not base 10, like the E above represents. the exponent part of a 32 bit float is 8 bits, representing a range from -126 to +127 (0xff has special meaning, so not included in the range )
The decimal part (the mantissa) defines the precision: It is 23 bits, and assumed to start with 1.X (the 1 BEFORE the decimal is not stored, just assumed), for a total of 24 bits of precision. This means that the least-significant-digit of the mantissa has a precision of: 1 part in 2^24 (or 0.00000011920928955078125 in decimal).
In other words- for any given exponent, there are 2^24 (about 16.7 million) different possible decimal values.
Okay, I think I understand it a bit more. The value 1.4123124234... can go out to further amounts of decimal places than the value 14123124.234...in the end though, both will have the same number of significant figures (if we assume all numbers are non-zero, because zero's a pain in sig figs).
If that's not right please let me know.
A range of 0 to 1 has fewer possible random unique bit combinations than the whole range of float.$$anonymous$$inValue to float.$$anonymous$$axValue which contains all of the possible combinations.
In this case, should one assign the $$anonymous$$ and max values? Can one even do that?
Basically, I'm planning to have a set of probabilities, say p=0.0000015 to start. Then Random.Range will run. Then if the result is <= 0.0000015, some action would happen.
I can probably multiply by some constant if that helps somehow, but will using Random.Range(0f, 1f) work to produce truly random results? How can I make it more "accurate" or "realistic?"
"go out to further decimal places": well- yes and no, depend on exactly what you mean. I think yes, the way you mean. but no as far as the way it's stored: 1.xxxxx(23bits) x 2^yyy(8bits)
When working with probability and random: rather use 1.0 to define the maximum probability, I'd use uint.$$anonymous$$axValue as the maximum. All my probabilities are then stored, and generated as unsigned integers. In fact, this will give you a greater (easily) useful range of different probabilities (32 bits, rather than the 23 used by the mantissa of a float: uint range: 0 to 4,294,967,295 ) edit: oh, looks like random range only does signed int, (or float), still you could probably just cast the result to an unsigned int.