IntValues (or at least standard ones do) definitely have limitations on the range ( -2,147,483,648 to 2,147,483,647) but Lua’s clever interpreter can expand values when they fall outside the standard range. I added a .0 to the end of OwnId so it would be interpreted as double precision and that number is well within the range of
( -1.797693134862315E+308 to -2.225073858507201E-308) but and it still doesn’t work. Odd…
There’s noint64_t data type in the Luau VM. The only numeric data type there are in Luau are IEEE binary64 (double) and vector, and because IEEE binary64 has a precision of the 53 most significant binary bits so integers up to 253 can be safely represented (and integers after that can only be safely represented in every 2s until 254 which integers after that can only be represented in every 4s, etc). IntValue.Value actually returns an int64_tcasted to a double which is printed in its shortest decimal representation so this…
…is not a bug.
However, IntValues internally stores the value as int64_t (from a double casted to int64_t), and because some integers after 253 cannot be exactly represented as a double, using IntValue is pointless.
as it’s rounded to its shortest decimal representation of a double.
In your Luau example script, both the INT_MAX and the INT_MIN local variable is actually a double and not an integer so it is rounded to the nearest representable value for the INT_MAX local variable.
Yeah I figured they must be using a double to represent 64bit int because of the overflow. But the IntValue info on the website clearly says they can hold the full range:
“An IntValue is an object that stores a single signed 64-bit integer. Integers do not include decimal points. The highest value that can be stored is 2^63-1, or around 9.2 quintillion. Attempting to store numbers larger than this may cause integer overflow. The lowest value that can be stored is -2^63, or about negative 9.2 quintillion”
And Roblox obviously have their own implementation of Lua so that’s why it was bugging me…
local OwnId = Instance.new("IntValue"); -- should be a full range 64bit int
OwnId.Value = 908779319084589067; -- this is below the threshold quoted on the website
for i=0, 10000 do
The output hints at boundary issues in the storage of signed character because of when the changes occur in the printed value, i.e. the print only skips to the next line when the value actually changes, the amount of times it prints shows the bits that had to change before it did change. The first few changes are shown below and you can see the value changes firstly on a half signed char step (+1), and then either one below or one above the signed character limit. This could indicate that the representation of signed char is incorrect in the Roblox’s Lua implementation (i.e. bits are overflowing/underflowing). Not sure, it’s odd and requires more testing.
If you run this from max value (i.e. INT64_MAX = 2 ^ 63-1) the issue is always represented along bit boundaries. Again a half step (+1) first and then full steps (+/-1) usually finishing with a quarter step (not shown):
But surely you would have to type this number manually into the string, which really isn’t a solution it’s a workaround which renders your original function redundant. You should be able to assign this to a string based off the number fitting into an IntValue and it successfully being cast to the correct string representation. The issue still exists, you just found a non-unique solution for the single case of that number.