Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Innacuracies with math.sqrt() and ^2 solution?

I was trying to determine if 3 points created a right triangle and was using the Pythagorean Theorem when I ran into a massive headache of a problem, which I'll get to in a little bit. The first thing I did was calculate the sidelengths using the following code

A,B,C=Vector3(10,0,0).new,Vector3.new(10,10,0),Vector3.new(0,10,0) --These are just example Vector3's for my problem
local CA=math.sqrt((A.X-C.X)^2+(A.Y-C.Y)^2+(A.Z-C.Z)^2)
local CB=math.sqrt((B.X-C.X)^2+(B.Y-C.Y)^2+(B.Z-C.Z)^2)
local BA=math.sqrt((A.X-B.X)^2+(A.Y-B.Y)^2+(A.Z-B.Z)^2)

Now for some strange reason

print(CB^2+BA^2, CA^2)
print(CB^2+BA^2==CA^2)

prints out

200,200
false

The only explanation I can think of is something with roblox rounding the numbers when displayed but behind the scenes these two numbers are ever so slightly askew due to innacuracies with math.sqrt() or ^2. Is there any way to get around this without losing significant accuracy?

2 comments

0

Using (num+.01/2)-((num+.000001/2)%.01) to round each number fixes the problem but this feels like an inefficient method, if it's all that can be done then I guess it'll suffice however I would really prefer not to have to do something like that,

0

Answered your comment

2 answers

✓ Accepted answer

Magnitude

Honeygold is most likely correct, and this is a floating-point comparison issue, but I would like to point out that you can skip doing this sort of length comparison with excessive math (Slow) by simply using

A,B,C=Vector3(10,0,0).new,Vector3.new(10,10,0),Vector3.new(0,10,0) --These are just example Vector3's for my problem
local CA=(A-C).magnitude
local CB=(B-C).magnitude
local BA=(A-B).magnitude

After that you can just compare closeness of them.

print(CB^2+BA^2, CA^2)
print(math.abs((CB^2+BA^2)-CA^2) < 0.001) -- Closer than 0.001 difference to eachother? They're probably realistically the same.

4 comments

0

Is .magnitude really any faster than just doing the math myself? I'm sure that using .magnitude just does almost exactly what I did myself but not visibly, the most variation I can imagine is avoiding x^2 with x*x

0

You have to remember that computing the magnitude C++ sided is going to probably be faster than doing it Lua sided, although I could be wrong as Roblox is really notorious for throwing logic out the window. Regardless, doing it from Lua technically gives you a more precise result (although not really important). The real question is, do you believe it's more readable to do the Pythagorean theorem

0

... to do the pythagorean theorem explicitly or to just use the Magnitude property of V3s?

0

Computing the magnitude C-side is going to be faster than computing it Lua-side, especially given the extra hidden metamethod invocations you're making by accessing X/Y/Z in each Vector3

I am almost certain that this is a floating-point error, which (long story short) prevents exact representation of numbers with decimals.

print(0.2 + 0.1 == 0.3) -- This prints false.
print((0.2 + 0.1) - 0.3 == 0) -- This prints false.
print((0.2 + 0.1) - 0.3 < 0.0000001) -- This prints true.

The fastest solution when checking for equality with decimals is to check if (the absolute value of) the difference is less than some small number.

This discussion is preserved as it was. New answers, comments, and votes are closed.