[Solved] Vector3f.equals giving bad results?

Hello everyone,
I need to compare a vector in my game to Vector3f.NAN:

System.out.println(closestFreeTreePosition);
System.out.println(!closestFreeTreePosition.equals(Vector3f.NAN));

This is what I’m doing. closestFreeTreePosition is a Vector3f that is set before these statements.
And I get for example this

(1.0f, 3.0f, 20.0f)
false

as output. Technically, it should be true, right?
Any ideas why this is happening?

No.

NaN is never equal to anything… not even NaN.

a) .equals() is a very bad way to compare vector3fs… since they would have to be identical in every way, which is almost never what you want for floating point.

b) it won’t work in this case anyway because NaN is never equal to anything… because it’s not a number.

If you want to know if a Vector3f’s elements are NaN then you have to check them with Float.isNaN().

Edit: adding a link to the Javadoc for isNaN(): Float (Java Platform SE 7 )

1 Like

Digging in the source code revealed the reason: Vector3f.equals uses Float.compare which can’t handle NANs:

1 Like

And that is why:

should be true (there is a negation in there)[quote=“pspeed, post:2, topic:38005”]
a) .equals() is a very bad way to compare vector3fs…
[/quote]

Thinking on this, wouldn’t it be useful to have an equals(Vector3f other, float equalityMargin) method on vector3f?

1 Like

Yes, and no. Comparing floating point numbers is a very very tricky subject.

1 Like

Ah, I missed the “not”.

In that case, I guess JME is doing bitwise comparison? Ah, they are using compare()…
if (Float.compare(x,comp.x) != 0) return false;
if (Float.compare(y,comp.y) != 0) return false;
if (Float.compare(z,comp.z) != 0) return false;

…which is good in some cases, I guess. But it’s weird in the case of NaN.

1 Like

Thanks guys.
Replacing the statement with
!Float.isNaN(closestFreeTreePosition.x)
fixed it.

Btw:
If you did not find a Position you could also return null, might be more obvious to implement.

And if I am not mistaken Vector3f already hast approximatelyEquals or something (but maybe only in regards to the length because for 3d the tollerance could have different methods (Sum of deviation over the components or max deviation per component mainly)

Probably going into details here, but isn’t it always best to try to return the object type question, even if it’s empty - rather than null?

For example, if I expected a method to return an array, and my method couldn’t for some reason - I’d probably return an empty array, not null. I was always taught that it’s better to do that then just return null by default behavior. Same for string or even integers. Return an empty string or -1 (if that is outside the int bounds) if possible, but not null.

It depends… null is better because you didn’t create an object you will just throw away and comparing something to null is much faster than making a method call.

It’s quite common to return null for “unknown” but it can depend on the method semantics. For example, arrays and collections are arguably cases where you might return an empty collection… because ‘empty’ makes sense in this context. (Edit: and often the caller will want to iterate over it right away and you save them some trouble.)

An ‘empty’ Vector3f doesn’t really exist.

1 Like