Integer overflow with math.randomseed?

For starters, what I believe I’ve found here is either a bug or something that just isn’t well documented. As the title states, any number over the 32 bit integer limit will produce the same random results as -2,147,483,648 when a random seed is set via math.randomseed.

The weird part about this is that the Random library is not affected by this at all. Here’s some code to reproduce the behavior:

math.randomseed(2147483648) -- any number over the 32 bit integer limit will do

for i = 1, 5 do
     print(math.random(1,5))
end

-- [OUTPUT]:
-- 1, 1, 1, 4, 5 

local Rand = Random.new(-2147483648)

for i = 1, 5 do
     print(Rand:NextInteger(1,5))
end

-- [OUTPUT]:
-- 1, 1, 1, 4, 5 

Is this behavior defined anywhere? I checked the wiki for both Random.new and math.randomseed and neither say anything about the limit for seeds but it’s pretty obvious there is one specifically for randomseed.

Just as one last confirmation that I’m not a lunatic, here’s the same code with different random results using the random library with the same seed as before:

local Rand = Random.new(2147483648)

for i = 1, 5 do
     print(Rand:NextInteger(1,5))
end

-- [OUTPUT]:
-- 4, 4, 5, 2, 3

Sorry if this is the wrong category for this type of thing, I don’t have access to post in #platform-feedback:engine-bugs

2 Likes

Sorry for necroposting. Might be useful for people reading this in the future.

math.randomseed casts C double to int for the random seed, which is an undefined behaviour on doubles out of the range of int:

In your case, the Luau binary in your case likely uses the instruction cvttsd2si CVTTSD2SI — Convert With Truncation Scalar Double Precision Floating-Point Value to SignedInteger to cast from double to integer, and double precision floating point values out of the signed doubleword range will return indefinite integer value, which happened to be 80000000H. It is probable that you’re on x86 as modern C compilers typically emit cvttsd2si and vcvttsd2si on x86 with SSE2. So the seed will be 80000000H. That is assuming the floating point exception is masked.