// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved. using System; using System.Collections.Generic; namespace FlaxEngine.Assertions { /// /// A float comparer used by Assertions.Assert performing approximate comparison. /// [HideInEditor] public class FloatComparer : IEqualityComparer { /// /// Default epsilon used by the comparer. /// public const float Epsilon = 1E-05f; /// /// Default instance of a comparer class with default error epsilon and absolute error check. /// public static readonly FloatComparer ComparerWithDefaultTolerance; private readonly float _error; private readonly bool _relative; static FloatComparer() { ComparerWithDefaultTolerance = new FloatComparer(1E-05f); } /// /// Creates an instance of the comparer. /// public FloatComparer() : this(Epsilon, false) { } /// /// Creates an instance of the comparer. /// /// /// Should a relative check be used when comparing values? By default, an absolute check will be /// used. /// public FloatComparer(bool relative) : this(Epsilon, relative) { } /// /// Creates an instance of the comparer. /// /// Allowed comparison error. By default, the FloatComparer.Epsilon is used. public FloatComparer(float error) : this(error, false) { } /// /// Creates an instance of the comparer. /// /// /// Should a relative check be used when comparing values? By default, an absolute check will be /// used. /// /// Allowed comparison error. By default, the FloatComparer.Epsilon is used. public FloatComparer(float error, bool relative) { _error = error; _relative = relative; } /// /// Performs equality check with absolute error check. /// /// Expected value. /// Actual value. /// Comparison error. /// /// Result of the comparison. /// public static bool AreEqual(float expected, float actual, float error) { return Math.Abs(actual - expected) <= error; } /// /// Performs equality check with relative error check. /// /// Expected value. /// Actual value. /// Comparison error. /// Result of the comparison. public static bool AreEqualRelative(float expected, float actual, float error) { if (expected == actual) return true; float single = Math.Abs(expected); float single1 = Math.Abs(actual); return Math.Abs((actual - expected) / (single <= single1 ? single1 : single)) <= error; } /// public bool Equals(float a, float b) { return !_relative ? AreEqual(a, b, _error) : AreEqualRelative(a, b, _error); } /// public int GetHashCode(float obj) { return GetHashCode(); } } }