Vector3f.equals() bug?

I was just fixing a bug in my game and came across this strange behaviour of Vector3f:

Vector3f v1 = new Vector3f(-0.0f, 1.0f, 2.0f);
Vector3f v2 = new Vector3f(0.0f, 1.0f, 2.0f);
System.out.println(v1.equals(v2));

Will result in

false

Although

float a = -0.0f;
float b = 0.0f;
System.out.println(a == b);

yields

true

I think this is inconsistent behaviour and should be changed. I already identified the problem in the Vector3f class itself. I uses Float.compare() == 0 to check if two values of the vector are equal. This works in all cases except for 0.0f and -0.0f. Because Float.compare returns an order for the given values and it is acceptable that -0.0 comes before 0.0 when ordering ascending. But still -0.0f and 0.0f are equal as values.

I highly recomment since its a floating class to NEVER do equality checks.
Always do a distance<Epsilon logic. Cause even in java the vm’s are allowed ( if not otherwise requested) to not use the iee floating points for performance.

1 Like

See here:
http://www.javapractices.com/topic/TopicAction.do?Id=17

Actually it uses Float.compare() instead of floatToIntBits, but the behavior should be the same.

I recommend you create your own equals() method like approximateEquals() that should do the comparison you want (with epsilons and whatnot).

Float.compare() internally uses floatToBitInts.

I think we have a missunderstanding here. This is not about comparing two possible different float values, but comparing two float values that are(!) equal when compared with ==. 0.0f and -0.0f are symantically equal, but not their IEEE 754 binary representation (because of the sign bit). That’s also why 0.0f == -0.0f is true. But of course I also know that two Float instances with 0.0f and -0.0f yield false when compared with a.equals(b).

So all in all I think of this not as a bug but as a design decision, and this way I’m willing to accept that :wink:
Case closed.