FMath::RandRange is broken when the size of the range is more than 0x7FFFFFFF

The way RandRange works is by calculating the size of the difference between the two numbers and using that to produce a random number with a helper function. However, the difference between the two integers is stored as a signed 32-bit integer, which doesn’t have a maximum value large enough to cover all use cases.

For example:

int randNum = FMath::RandRange(-1, INT32_MAX);

This code would result in undefined behaviour because (INT32_MAX - -1) = INT32_MAX + 1 which cannot be stored as a 32 bit signed value.

The code might need some rework to fix correctly, so it might be worth warning that such ranges are not supported in the documentation for now.

Hi ceph3us,

The RandHelper() function does actually provide a check for this situation. RandHelper() returns a random integer between 0 and the range value if the range is greater than 0. If the range is 0 or a negative value, RandHelper() always returns 0. RandRange() then takes that value and adds it to the minimum value that you specified. In the example case you provided, the range that is being passed into RandHelper() is -2147483648, so it will return 0 and you will find that every time you try to get a random value between -1 and INT32_MAX, you will always get -1 back. This is working as intended.

However, you do make a valid point that this limitation is probably not communicated very clearly. What is your use case where you need a random number within a range greater than 2147483647?

I was generating a few pseudorandom bytes for an anonymous identifier to help track gameplay metrics during our gameplay test.

For the record: right now I’m just requesting chunks at a time and doing bitshifts.

I am curious if a GUID may work better for you in this instance. It would allow you to have a truly unique identifier for each object that needs one. Using RandRange() wouldn’t provide any guarantee of uniqueness unless you were tracking that yourself.

Another possibility, if you really need to use bytes in this case, might be to use RandRange(0,255) multiple times and store the results in a byte buffer. However, this also does not provide any guarantees of uniqueness.

It’s being used as an ‘anonymisation factor’ - we’re basically salting identifiers we do know are unique so that they can’t be recreated to identify users.