Regular sin(x) returns 0 when x = pi and x = 0, then why on earth does math.sin(x) return 1.2246467991474e-16 in Roblox when x = pi, and what would the value for x need to be to get math.sin(x) to return 0 except when x = 0?
Edit: This is very odd. If I do math.sin(3.14) then it returns 0.0015926529164868, which is very close to 0, but if I add the two next numbers in pi to that, then math.sin(3.1415) gives me 9.265358966049e-05.
This just sounds like a floating point precision issue. 1e-16 is so small it might as well be treated as 0. Note the negative sign, this is actually 0.0000000000000001.
This is because math.pi isn’t truly pi. All numbers in lua are double-point floating-precision numbers, a subset of real numbers that can not express all real numbers. As such, an operation like 1 + 2 can sometimes be 2.999; ~3. The solution, if need be, might be to have a small range of values you accept as being equal to the integer value of 0.
You could but I don’t see this causing many issues on its own if you’re calculating a bunch of things. If you’re comparing you might want to test <= eps or similar instead of ==.
What would be the most accurate way to round it down though? As math.floor rounds down towards the closest full number and the decimals are important in my use-case.
Edit: What I’ve previously done is basically math.floor(number*1000 + .5)/1000 but I don’t know if that’s the best way to go about this.
I did actually not know that. I have never done mathematics where e-16 or e+16 etc. has been used as we use something else for that in school and on Roblox the numbers I usually work with never go that low so that’s good to know.
It depends on what precision you desire. In essence, you can do the following. Here is an example annotated with Luau type annotations for clarity:
--- Function that rounds the given value to the given precision.
local function round(value: number, precision: number?): number
local precision = precision or 0;
local factor = 10 ^ precision;
assert(precision >= 0, "The given precision must be a positive number or zero!");
assert(math.floor(precision) == precision, "The given precision must be an integer!");
return math.floor(value * factor + 0.5) / factor;
end
print(round(20.757)) -- Rounds to the nearest integer
-- Prints "21"
print(round(-20.757, 1)) -- Rounds to the nearest tenth
-- Prints "-20.8"
print(round(20.757, 2)) -- Rounds to the nearest hundredth
-- Prints "20.76"