Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Mathf.Approximately with custom epsilon

Discussion in 'General Discussion' started by FIFTYTWO, Oct 24, 2020.

  1. FIFTYTWO

    FIFTYTWO

    Joined:
    Oct 21, 2014
    Posts:
    49
    I'd like to implement my own Approximately with custom epsilon. Unity's Mathf source has the following implementation:

    Code (CSharp):
    1. public static bool Approximately(float a, float b)
    2. {
    3.     // If a or b is zero, compare that the other is less or equal to epsilon.
    4.     // If neither a or b are 0, then find an epsilon that is good for
    5.     // comparing numbers at the maximum magnitude of a and b.
    6.     // Floating points have about 7 significant digits, so
    7.     // 1.000001f can be represented while 1.0000001f is rounded to zero,
    8.     // thus we could use an epsilon of 0.000001f for comparing values close to 1.
    9.     // We multiply this epsilon by the biggest magnitude of a and b.
    10.     return Abs(b - a) < Max(0.000001f * Max(Abs(a), Abs(b)), Epsilon * 8);
    11. }
    12.  
    Where 0.000001f is the epsilon.

    So, I have two questions

    1. Why MAX and not MIN magnitude is used for threshold calculation? I saw a function in QT where MIN is used:

    Code (CSharp):
    1. Q_REQUIRED_RESULT Q_DECL_CONSTEXPR static inline Q_DECL_UNUSED bool qFuzzyCompare(float p1, float p2)
    2. {
    3.     return (qAbs(p1 - p2) * 100000.f <= qMin(qAbs(p1), qAbs(p2)));
    4. }
    which can be rewritten as qAbs(p1 - p2) <= 0.00001f * qMin(qAbs(p1), qAbs(p2));

    2. Unity's Approximately() has a zero comparison protection choosing maximum of threshold or Epsilon * 8, where Epsilon is minimal non-zero positive float. Should I adjust Epsilon * 8 if in my custom implementation or leave as is? Is this implementation fine?

    Code (CSharp):
    1. public static bool Approximately(float a, float b, float epsilon)
    2. {
    3.     return Abs(b - a) < Max(epsilon * Max(Abs(a), Abs(b)), Epsilon * 8);
    4. }
    5.