mirror of
https://github.com/Ryujinx/Opentk.git
synced 2025-09-15 15:57:14 +00:00
Merged new equivalence function.
This commit is contained in:
parent
fb71ebcffe
commit
87de6dda4d
|
@ -422,6 +422,50 @@ namespace OpenTK
|
||||||
return relativeError < epsilon;
|
return relativeError < epsilon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Approximates equivalence between two single-precision floating-point numbers on a direct human scale.
|
||||||
|
/// It is important to note that this does not approximate equality - instead, it merely checks whether or not
|
||||||
|
/// two numbers could be considered equivalent to each other within a certain tolerance.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="a">The first value to compare.</param>
|
||||||
|
/// <param name="b">The second value to compare·</param>
|
||||||
|
/// <param name="tolerance">The tolerance within which the two values would be considered equivalent.</param>
|
||||||
|
/// <returns>Whether or not the values can be considered equivalent within the tolerance.</returns>
|
||||||
|
[SuppressMessage("ReSharper", "CompareOfFloatsByEqualityOperator")]
|
||||||
|
public static bool ApproximatelyEquivalent(float a, float b, float tolerance)
|
||||||
|
{
|
||||||
|
if (a == b)
|
||||||
|
{
|
||||||
|
// Early bailout, handles infinities
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
float diff = Math.Abs(a - b);
|
||||||
|
return diff < tolerance;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Approximates equivalence between two double-precision floating-point numbers on a direct human scale.
|
||||||
|
/// It is important to note that this does not approximate equality - instead, it merely checks whether or not
|
||||||
|
/// two numbers could be considered equivalent to each other within a certain tolerance.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="a">The first value to compare.</param>
|
||||||
|
/// <param name="b">The second value to compare·</param>
|
||||||
|
/// <param name="tolerance">The tolerance within which the two values would be considered equivalent.</param>
|
||||||
|
/// <returns>Whether or not the values can be considered equivalent within the tolerance.</returns>
|
||||||
|
[SuppressMessage("ReSharper", "CompareOfFloatsByEqualityOperator")]
|
||||||
|
public static bool ApproximatelyEquivalent(double a, double b, double tolerance)
|
||||||
|
{
|
||||||
|
if (a == b)
|
||||||
|
{
|
||||||
|
// Early bailout, handles infinities
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
double diff = Math.Abs(a - b);
|
||||||
|
return diff < tolerance;
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
|
@ -11,8 +11,13 @@ module private AssertHelpers =
|
||||||
[<Literal>]
|
[<Literal>]
|
||||||
let private BitAccuracy = 16
|
let private BitAccuracy = 16
|
||||||
|
|
||||||
|
[<Literal>]
|
||||||
|
let private EquivalenceTolerance = 0.0001f
|
||||||
|
|
||||||
|
let approxEq a b = MathHelper.ApproximatelyEquivalent(a, b, EquivalenceTolerance)
|
||||||
//let approxEq a b = MathHelper.ApproximatelyEqual(a,b,BitAccuracy)
|
//let approxEq a b = MathHelper.ApproximatelyEqual(a,b,BitAccuracy)
|
||||||
let approxEq a b = MathHelper.ApproximatelyEqualEpsilon(a,b,0.0001f)
|
//let approxEq a b = MathHelper.ApproximatelyEqualEpsilon(a,b,0.0001f)
|
||||||
|
|
||||||
let approxEqSingleEpsilon a b = MathHelper.ApproximatelyEqualEpsilon(a, b, 0.00001f)
|
let approxEqSingleEpsilon a b = MathHelper.ApproximatelyEqualEpsilon(a, b, 0.00001f)
|
||||||
let approxEqDoubleEpsilon a b = MathHelper.ApproximatelyEqualEpsilon(a, b, 0.00001)
|
let approxEqDoubleEpsilon a b = MathHelper.ApproximatelyEqualEpsilon(a, b, 0.00001)
|
||||||
|
|
||||||
|
|
|
@ -305,4 +305,48 @@ module MathHelper =
|
||||||
Assert.NotApproximatelyEqualEpsilon(0.000000001, -System.Double.Epsilon);
|
Assert.NotApproximatelyEqualEpsilon(0.000000001, -System.Double.Epsilon);
|
||||||
Assert.NotApproximatelyEqualEpsilon(0.000000001, System.Double.Epsilon);
|
Assert.NotApproximatelyEqualEpsilon(0.000000001, System.Double.Epsilon);
|
||||||
Assert.NotApproximatelyEqualEpsilon(System.Double.Epsilon, 0.000000001);
|
Assert.NotApproximatelyEqualEpsilon(System.Double.Epsilon, 0.000000001);
|
||||||
Assert.NotApproximatelyEqualEpsilon(-System.Double.Epsilon, 0.000000001);
|
Assert.NotApproximatelyEqualEpsilon(-System.Double.Epsilon, 0.000000001);
|
||||||
|
|
||||||
|
[<Properties(Arbitrary = [| typeof<OpenTKGen> |], MaxTest = 10000)>]
|
||||||
|
module ``ApproximatelyEquivalent (tolerance diff)`` =
|
||||||
|
[<Fact>]
|
||||||
|
let ``ApproximatelyEquivalent correctly approximates equivalence where the difference falls below the tolerance``() =
|
||||||
|
let a = 0.0001f
|
||||||
|
let b = 0.00019f
|
||||||
|
Assert.NotEqual(a,b)
|
||||||
|
Assert.True(MathHelper.ApproximatelyEquivalent(a, b, 0.0001f))
|
||||||
|
|
||||||
|
[<Fact>]
|
||||||
|
let ``ApproximatelyEquivalent correctly approximates inequivalence where the difference is the tolerance``() =
|
||||||
|
let a = 0.0001f
|
||||||
|
let b = 0.0002f
|
||||||
|
Assert.NotEqual(a,b)
|
||||||
|
Assert.False(MathHelper.ApproximatelyEquivalent(a, b, 0.0001f))
|
||||||
|
|
||||||
|
[<Fact>]
|
||||||
|
let ``ApproximatelyEquivalent correctly approximates inequivalence where the difference exceeds the tolerance``() =
|
||||||
|
let a = 0.0001f
|
||||||
|
let b = 0.00021f
|
||||||
|
Assert.NotEqual(a,b)
|
||||||
|
Assert.False(MathHelper.ApproximatelyEquivalent(a, b, 0.0001f))
|
||||||
|
|
||||||
|
[<Fact>]
|
||||||
|
let ``ApproximatelyEquivalent reports very different values as non-equal even with a high tolerance``() =
|
||||||
|
let a = 2.0f
|
||||||
|
let b = 1.0f
|
||||||
|
Assert.NotEqual(a,b)
|
||||||
|
Assert.False(MathHelper.ApproximatelyEquivalent(a, b, 1.0f))
|
||||||
|
|
||||||
|
[<Fact>]
|
||||||
|
let ``ApproximatelyEquivalent works with single zero value``() =
|
||||||
|
let a = 1.0f
|
||||||
|
let b = 0.0f
|
||||||
|
Assert.NotEqual(a,b)
|
||||||
|
Assert.False(MathHelper.ApproximatelyEquivalent(a, b, 0.0001f))
|
||||||
|
|
||||||
|
[<Fact>]
|
||||||
|
let ``ApproximatelyEquivalent works with both zero values``() =
|
||||||
|
let a = 0.0f
|
||||||
|
let b = 0.0f
|
||||||
|
Assert.Equal(a,b)
|
||||||
|
Assert.True(MathHelper.ApproximatelyEquivalent(a, b, 0.0001f))
|
Loading…
Reference in a new issue