Hello developers! I’ve come across this and I don’t know what this means.
My script prints out -nan(ind) whenever i put a big number in this function.
local Functions = {
Default = function(n)
local v = 1
for i = 2, n do
v = v * i
end
return v -- Basically creating a factorial function
end,
Class = function(n, k)
local fac = require(script).Default
return fac(n) / fac(n - k) -- The factorial function but instead of all the numbers it just uses the last (some number) numbers.
end
}
print(Functions.Class(100000, 2)) -- This should be printing out 100K multiplied by 99,999, instead it's printing "-nan(ind)"
This is a big issue for my game since the class function can return a sum of 1 to any number and I need that for calculations in my game.
Because dividing an infinite number with another infinite number in Luau will result in -nan(ind) “number”. fac(n) turns into infinite when n is anything higher or equal to 171 because of how big the number is (~1.7976931336163e+308 is the limit before Luau turns the number into infinite, or 2^1023.999999999… in another terms.).
So when you pass anything higher or equal to 173 to Functions.Class(n, 2), it will make both fac(n) and fac(n - k) infinite numbers so Luau returns -nan(ind) when you divide them.
You can’t really fix this limitation, all numbers in Luau are double-precision floating point numbers that uses IEEE 754 format. Which means out of 64 bits used to store the number, 1 is used for storing the sign of number, 11 used for exponent which stores a 11 bit integer and 52 bits for fraction for the rest for precision.
You could try to get around this problem by using a library to store integers bigger than 2^53 without precision loss like BigInteger library made by @Blockzez but obviously, this solution does not use native double-precision floating point numbers in Luau (Well, it technically does to store tables of base 2 in little-endian order but I digress.) so it’s a lot slower and obviously has some limitations to it.