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);
Will result in
float a = -0.0f;
float b = 0.0f;
System.out.println(a == b);
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
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 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.
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 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
false when compared with
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