if (horizontalAxis != 0) Epsilon Question

So, I have

if (hAxis != 0)

Visual Studio accepts it, but is warning me about it, suggesting I should possibly use epsilon.

Having never used ‘epsilon’ before, and getting confused with the documentation, what would be the best way to fix this warning ?

or just simply do something like this instead ? :

if (hAxis < 0 | hAxis > 0)

Thanks

You’re using floats?

Against advice with respect to floating point values, I’ve found (empirically) that comparing a float to 0 doesn’t appear to suffer from floating point weirdness. (Compared to, say, comparing a float to 0.1). However, generally for float “equality”, you’d want to use something like Mathf.Approximately() for the comparison. That doesn’t allow you to specify your own epsilon value, but it’s typically all you need in Unity.

And the idea with “epsilon” is that, by convention, epsilon is expected to be a very small value. And you’d use it in a method to test whether two float values are within a small distance from each other. Like this:

        public static bool AreClose(float a, float b, float epsilon = 0.0001f)
        {
            return Mathf.Abs(a - b) < epsilon;
        }

But I’d probably just use Mathf.Approximately for float comparisons, unless you know you need a different epsilon value.

Edit: And just to make sure you’re aware, at a high level, of why this kind of thing is necessary, computers don’t store floats in a highly precise way. The value 0.1 is actually stored as something like 0.1000000003, or something like that. So, when trying to compare two floats, those inaccuracies in the decimal places far to the right of the decimal place can cause two numbers not to be considered equal, because they’re actually .000000001 different. That’s why we use this “Approximately” or “AreClose” approach, because in general, anything that’s equal to 5 decimal places is usually “close enough” when it comes to game logic.

1 Like

Thanks for the detailed breakdown.

It’s for the rotation of a gameObject, so I think I’m probably fine with :

if (hAxis < 0 | hAxis > 0)
        {
            rotationY.Set(0f, hAxis, 0f);
            rotationY = rotationY * rotationSpeed;
            Quaternion deltaRotation = Quaternion.Euler(rotationY);
            playerBody.MoveRotation(playerBody.rotation * deltaRotation);
        }

It works fine in Unity anyway, without any problems.

if(!Mathf.Approximately(hAxis, 0f))
1 Like

This isn’t really fixing the underlying issue, though, it’s just tricking the compiler into missing it.

My guess here is that you’re reading from an input source which will give you results which are genuinely equal to 0, so t happens to work as expected and you’re fine.

What the compiler was complaining about is that once you’ve performed some arbitrary operations on a floating point number, the chances of it being exactly equal to any specific number are quite slim. Even in the Unity editor you’ll sometimes notice position and rotation numbers being something like “1.9997e-7”, which is because after some calculations Unity got to a number that was pretty close to zero, but the numbers didn’t work out perfectly. When compared for equality against zero that would return “false”, even though it is probably what we would want to interpret it as.

When working with floating point numbers, you should always try to design your code to use boundary values rather than to end up on exact figures. If you can’t, using Mathf.Approximately(x, y) checks to see if they’re close enough that the difference is likely to be floating point imprecision.

1 Like