// Copyright (c) 2012-2022 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();
}
}
}