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 
Case closed.