Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is Mathf.Approximately(0.0f, float.Epsilon) == true its correct behavior?

I have just noticed that the following code returns true:

Mathf.Approximately(0.0f, float.Epsilon); // true

I have read the Mathf.Approximately Documentation and it states that:

Approximately() compares two floats and returns true if they are within a small value (Epsilon) of each other.

And Mathf.Epsilon Documentation states that:

  • anyValue + Epsilon = anyValue
  • anyValue - Epsilon = anyValue
  • 0 + Epsilon = Epsilon
  • 0 - Epsilon = -Epsilon

As a result, I ran the following code, expecting it to be false, but it also returns true.

Mathf.Approximately(0.0f, 2.0f * float.Epsilon); // true

By the way:

Mathf.Approximately(0.0f, 2.0f * float.Epsilon); // true
Mathf.Approximately(0.0f, 3.0f * float.Epsilon); // true
Mathf.Approximately(0.0f, 4.0f * float.Epsilon); // true
Mathf.Approximately(0.0f, 5.0f * float.Epsilon); // true
Mathf.Approximately(0.0f, 6.0f * float.Epsilon); // true
Mathf.Approximately(0.0f, 7.0f * float.Epsilon); // true

Mathf.Approximately(0.0f, 8.0f * float.Epsilon); // false
Mathf.Approximately(0.0f, 9.0f * float.Epsilon); // false

Q: Based on that evidence, can I safely say that Mathf.Approximately is not correctly implemented according to its documentation*?

(* and as a result, I should move to different solutions, such as the one in Floating point comparison functions for C#)

like image 290
ianmandarini Avatar asked Oct 28 '19 22:10

ianmandarini


People also ask

What is Mathf Epsilon?

Description. A tiny floating point value (Read Only). The smallest value that a float can have different from zero. With the following rules: anyValue + Epsilon = anyValue.

What is the value of float Epsilon?

The value of the Epsilon property is not equivalent to machine epsilon, which represents the upper bound of the relative error due to rounding in floating-point arithmetic. The value of this constant is 1.4e-45.

How to compare floating point numbers for equality?

If we do have to compare two floating-point numbers then rather than using “==” operator we will find the absolute difference between the numbers (which if were correctly represented, the difference would have been 0) and compare it with a very small number 1e-9 (i.e 10^-9, this number is very small) and if the ...


1 Answers

Here is the decompiled code of Unity's public static bool Mathf.Approximately(float a, float b); You can see the * 8.0f at the end ^^, so a truely badly documented method indeed.

/// <summary>
/// <para>Compares two floating point values if they are similar.</para>
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
public static bool Approximately(float a, float b)
{
   return (double) Mathf.Abs(b - a) < (double) Mathf.Max(1E-06f * Mathf.Max(Mathf.Abs(a),
       Mathf.Abs(b)), Mathf.Epsilon * 8.0f);
}
like image 165
Menyus Avatar answered Nov 14 '22 23:11

Menyus