You should never compare floating point values for equality using the following operators:

- ==
- <=
- >=

float a = 2.0f; float b = a; // any of these is best avoided if(a == b) { // you expect it to work but sometimes it won't } if(a <= b) { // you expect it to work but sometimes it won't } if(a >= b) { // you expect it to work but sometimes it won't }

Why? The short answer is because the representation of floating numbers is not consistent such that two floats may have the same perceived value but differ in bit representation. The long answer is here.

So how do we compare floats for equality then? If you’re using Unity, Mathf.Approximately() is very handy. Here’s a full Comparison class using exactly that:

using UnityEngine; /** * Class for comparing floating point values */ public static class Comparison { /** * Returns whether or not a == b */ public static bool TolerantEquals(float a, float b) { return Mathf.Approximately(a, b); } /** * Returns whether or not a >= b */ public static bool TolerantGreaterThanOrEquals(float a, float b) { return a > b || TolerantEquals(a, b); } /** * Returns whether or not a <= b */ public static bool TolerantLesserThanOrEquals(float a, float b) { return a < b || TolerantEquals(a, b); } }

If you’re not using Unity, you should define a tolerance value such that any value less then this is considered meaningless. This may vary across different games and applications. To define equality, we just take the absolute value of the difference of the two floating values and compare if this is lesser than the tolerance value. If it is, we can say that the two floating values are equal. In other words, we are merely discarding floating values that are already too small to be significant for our use.

using System; /** * Class for comparing floating point values */ public static class Comparison { private const float TOLERANCE_VALUE = 0.0001f; /** * Returns whether or not a == b */ public static bool TolerantEquals(float a, float b) { return Math.Abs(a - b) < TOLERANCE_VALUE; } /** * Returns whether or not a >= b */ public static bool TolerantGreaterThanOrEquals(float a, float b) { return a > b || TolerantEquals(a, b); } /** * Returns whether or not a <= b */ public static bool TolerantLesserThanOrEquals(float a, float b) { return a < b || TolerantEquals(a, b); } }

Finally, the following are the sample usage:

float a = 2.0f; float b = a; // these are better if(Comparison.TolerantEquals(a, b)) { // now this works as expected } if(Comparison.TolerantLesserThanOrEquals(a, b)) { // now this works as expected } if(Comparison.TolerantGreaterThanOrEquals(a, b)) { // now this works as expected }

Now look at your code and see if you’re making this mistake. This may be the source of bugs that you couldn’t solve before.

## One thought on “A Generic Floating Point Comparison Class”