0/0 == 0/0 should return false, yet when comparing a NaN Vector3 to itself, it now returns true.
Yesterday, Vector3 and CFrame did not behave this way.
local v = Vector3.new(0/0, 0/0, 0/0)
local c = CFrame.new(0/0, 0/0, 0/0)
print(v == v) -- true
print(c == c) -- true
print(v.x == v.x and v.y == v.y and v.z == v.z) -- false
Almost anytime I unitize a vector, I do a NaN check by comparing it against itself. I guess I have been doing this since 2019.
So now I’m leaking NaN Vector3s everywhere.
Wow I never organically came across this case when programming in vanilla Lua.
In the long term it’s probably better to keep more parity with vanilla Lua.
I will be changing all of my NaN checking code over to be in line with vanilla functionality.
This change has been reverted, sorry for the chaos - this wasn’t expected to go south We’re going to reevaluate this decision internally. It’s possible that it’s worthwhile to implement the feature request I linked instead of going back to the old Lua behavior.
If the old behavior has a meaningful performance benefit, then maybe post a notice and try restoring it another time. I would push for whatever behavior has the best performance overall, because NaN will be confusing either way.
Use case 1: You add an arbitrary userdata to a table and expect to be able to remove it using table.find. One could compare this to inserting NaN itself, so it’s not obvious what the behavior should be.
Use case 2: You need to check if a userdata contains NaN. It may also be important to check for math.huge and -math.huge.
Equal-but-not-rawequal edge cases also surface when using userdata keys in tables, so that might be something to consider when deciding on __eq behaviors:
local t = {}
local v = Vector3.new(0, 0, 0)
t[v] = true
print(t[v]) -- true
print(t[Vector3.new(0, 0, 0)]) -- nil
We need to fix something either way - one fun fact is that table.find actually does use the rawequal check:
> local v = Vector3.new(0/0, 0, 0) local t = {v} print(table.find(t, v), t[1] == v)
1 false
There’s not really a performance difference either way unless you’re in the habit of comparing objects to themselves and expect this to be super fast… My initial inclination was to restore compatibility with Lua but since it’s now something that games depend on we could go back and instead honor the metatable-provided __eq regardless of raw equality which gives a more consistent behavior.