Unity's lack of consistency with Random.Range

I don’t know where to put this, but maybe someone that works for Unity will see it. I had to find out the hard way that, even though the Range is inclusive on the max side for floats, it is exclusive for integers. Do we have to pour over the manual to find inconsistencies like this? Or do we slowly realize that the top range never gets chosen on ints only! It’s not a bug. It’s just bad form. Sorry if it’s in the wrong place.

1 Like

The description of both methods basically only talks about this difference, and both methods are on the same script reference page. Not a lot of pouring over needed.

As far as why this is the case, here is my guess. System.Random is exclusive for the max value of an integer just the same as Unity’s version. There isn’t a System.Random version for floats, but there is for doubles which is also exclusive. If Unity is using System.Random to generate a random double and then using Convert.ToSingle(Double) to get a float from it, that includes the possibility that it could round up to the float max value. So instead of adding an additional check for that (making the process take longer), they just mark it as inclusive.

I have no idea if that is how it is implemented today, but if I were on the Unity team back for version 1 that is how I would have done it to get things working, and then even if optimized later to no longer convert doubles to floats, I wouldn’t change the way Unity users call the method. You do that and you get an even bigger outcry than this minor inconsistency.

1 Like

Actually it’s much worse than that and I think this is worth mentioning because I too would like a unity developer to see this.

Random.Range is exclusive on the max value for ints, except for when the max value is just 1 difference. such as Random.Range (0,2) will get either 0 or 1, and Random.Range(0,1) will also get 0 or 1. Which is very annoying and throws a lot of ‘out of bounds’ type errors when you’re using it like thing = array[Random.Range(0, array.Length)]; because if your array has anything over 1 in Length, its fine, but if the length is 1, then you have a 50/50 chance of getting an index out of range error.

That is a seriously annoying inconsistency. I understand for the layman perhaps writing Random.Range(0,1) always being equal to 0 might seem weird, but when from an experienced programming point of view, that’s exactly what you want it to be, otherwise you need to constantly write extra checks for out of bound indexes.

Have you tested this? Random.Range( 0, 1 ) always returns 0. Are you sure that whatever you’re using Random.Range( 0, array.Length ) for doesn’t just sometimes have an empty array?

If the built-in random range method were to have that stated issue, why would you write bounds checks instead of just implementing your own random range method that works how you want it to?