This is probably a bit of an inane question, but I’m curious.
Why are the arguments for the float one [inclusive], [inclusive] and for the integer one [inclusive], [exclusive]. Is there some technical reason for the discrepancy or is it just arbitrary?
1 Like
Actually as of Unity 5, this is no longer the case. Both versions (int and float) are documented as maximally exclusive. Haven't tested to verify but that's a subtle change that can cause some interesting statistical issues for existing code.
Yep I believe it. I was being sarcastic, Unity docs are of course far from perfect. When in doubt, see what it does in reality. Thx for verifying the Unity 5 docs are in error, and please disregard my initial comment!
I think it is just for convinience. For example, if you have an array of 10 objects and that you want to select a random object in that array, you could simply do myArray[Random.Range(0,myArray.Length)]; and you wouldn’t have to worry with the -1 because the indexes in the array are [0,9]. For the float, take for example if I want to set an animation to a random time between 0 and 1, I could just do myAnim["walk"].time = Random.Range(0f,1f); so it would include all of the animation’s frame. So I really think that it is just for convinience. Hope it helps :).
Have a great day.
Claude
Yea I just used it for accessing an array after posting this and that use did occur to me.
I think that this is for convenience, but implementation-wise rather than usage since an inclusive range would require a few more instructions which require additional user code to become exclusive again. Whilst the performance difference would be tiny, people should only pay for what they use. That would be my reason for implementing it this way.
Though this may not be the case with Unity’s implementation of their random functions, based upon my previous experience this is due to the way in which the random numbers are generated.
Random Integers
Random integers can be generated between 0 and the largest representable integer int.MaxValue. Now you want to get a random value between a specific minimum and maximum value so the following formula can be used:
public static int RandomInteger(int minInclusive, int maxExclusive) {
int randomInteger = SomeRandomNumberGeneratorAlgorithm();
int range = maxExclusive - minInclusive;
return minInclusive + randomInteger % range;
}
If randomInteger can be any positive integer then the above will produce values >= minInclusive and < maxExclusive.
Random Floats
Random floats can be generated using a function like the followings:
public static float RandomFloat(float minInclusive, float maxInclusive) {
int randomInteger = SomeRandomNumberGeneratorAlgorithm();
// Convert to a value between 0f and 1f:
float randomFloat = (float)randomInteger / (float)int.MaxValue;
float range = maxInclusive - minInclusive;
return minInclusive + randomFloat * range;
}
Random values generated with this function are inclusive of both the user specified minimum and maximum values.
Warning: Above snippets have not been tested, but I am pretty sure I got those right
Just to be clear, if I were making a dice roller using integers and I wanted to roll on a 20-sided die, I would need: int roll = Random.Range(1,21); NOT int roll = Random.Range(1,20); Correct??
Note: none of this will make sense unless you understand how modulus works (feel free to look it up, its not particularly complicated).
In c++ to get a random value, you call rand() which returns any int value. To get values in a range like unity gives you would have something like:
public static int Range(int min, int max)
{
int randomValue = rand();
int range = max - min;// The possible difference in values between min and max.
return min + randomValue % range;
}
So for example calling Range(0, 10) would have
range = 10 - 0
resulting in:
return 0 + randomValue % 10;
When you modulus any number by 10, you’ll get a number from 0 to 9, aka Range() can be said to be [inclusive], [exclusive].
On the other hand, I have no clue how you would get a random float value but i suspect that the difference is what causes it to be [inclusive], [inclusive]. So yes, I believe there is probably a technical reason but I’m not sure exactly what it is.
Not terribly important, but a slight correction, the rand() function in C only returns zero and positive integers.
Actually to use the int values for Random.Range just add 1 to the array like so
GameObject newEnemy = Instantiate (Enemies [Random.Range(0,3)]) as GameObject;
It works in my code when the array only has 3 elements not 4. I tried the ‘Random.Range(0,2)+1’ and it didn’t work for me but this code does and has a chance to spawn all three.
Actually as of Unity 5, this is no longer the case. Both versions (int and float) are documented as maximally exclusive. Haven't tested to verify but that's a subtle change that can cause some interesting statistical issues for existing code.
– sampenguin@sampenguin This is in fact still the case, the new Unity docs are just wrong.
– numberkruncherha! Unity docs being wrong? Impossible! :P
– sampenguinIf you take Random.Range(Single.MaxValue - 1f, Single.MaxValue) you will occasionally get Single.MaxValue. To me that means it's inclusive...
– cjdevYep I believe it. I was being sarcastic, Unity docs are of course far from perfect. When in doubt, see what it does in reality. Thx for verifying the Unity 5 docs are in error, and please disregard my initial comment!
– sampenguin