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
[<Literal>]
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.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 approxEqDoubleEpsilon a b = MathHelper.ApproximatelyEqualEpsilon(a, b, 0.00001)
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);
\ No newline at end of file
+ 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))
\ No newline at end of file