Added more unit tests to the floating point helper classes; Variegator unit test is now internal
git-svn-id: file:///srv/devel/repo-conversion/nusu@287 d2e56fa2-650e-0410-a79f-9358c0239efd
This commit is contained in:
parent
2462dd6dc4
commit
63ddef021d
|
@ -188,7 +188,7 @@
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Source\Collections\Variegator.cs" />
|
<Compile Include="Source\Collections\Variegator.cs" />
|
||||||
<Compile Include="Source\Collections\Variegator.Test.cs">
|
<Compile Include="Source\Collections\Variegator.Test.cs">
|
||||||
<DependentUpon>TransformingReadOnlyCollection.cs</DependentUpon>
|
<DependentUpon>Variegator.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="Source\Collections\WeakCollection.cs" />
|
<Compile Include="Source\Collections\WeakCollection.cs" />
|
||||||
<Compile Include="Source\Collections\WeakCollection.Interfaces.cs">
|
<Compile Include="Source\Collections\WeakCollection.Interfaces.cs">
|
||||||
|
|
|
@ -217,6 +217,10 @@
|
||||||
<Compile Include="Source\Collections\TransformingReadOnlyCollection.Test.cs">
|
<Compile Include="Source\Collections\TransformingReadOnlyCollection.Test.cs">
|
||||||
<DependentUpon>TransformingReadOnlyCollection.cs</DependentUpon>
|
<DependentUpon>TransformingReadOnlyCollection.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Source\Collections\Variegator.cs" />
|
||||||
|
<Compile Include="Source\Collections\Variegator.Test.cs">
|
||||||
|
<DependentUpon>Variegator.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Source\Collections\WeakCollection.cs" />
|
<Compile Include="Source\Collections\WeakCollection.cs" />
|
||||||
<Compile Include="Source\Collections\WeakCollection.Interfaces.cs">
|
<Compile Include="Source\Collections\WeakCollection.Interfaces.cs">
|
||||||
<DependentUpon>WeakCollection.cs</DependentUpon>
|
<DependentUpon>WeakCollection.cs</DependentUpon>
|
||||||
|
|
|
@ -228,6 +228,10 @@
|
||||||
<Compile Include="Source\Collections\TransformingReadOnlyCollection.Test.cs">
|
<Compile Include="Source\Collections\TransformingReadOnlyCollection.Test.cs">
|
||||||
<DependentUpon>TransformingReadOnlyCollection.cs</DependentUpon>
|
<DependentUpon>TransformingReadOnlyCollection.cs</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="Source\Collections\Variegator.cs" />
|
||||||
|
<Compile Include="Source\Collections\Variegator.Test.cs">
|
||||||
|
<DependentUpon>Variegator.cs</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Source\Collections\WeakCollection.cs" />
|
<Compile Include="Source\Collections\WeakCollection.cs" />
|
||||||
<Compile Include="Source\Collections\WeakCollection.Interfaces.cs">
|
<Compile Include="Source\Collections\WeakCollection.Interfaces.cs">
|
||||||
<DependentUpon>WeakCollection.cs</DependentUpon>
|
<DependentUpon>WeakCollection.cs</DependentUpon>
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace Nuclex.Support.Collections {
|
||||||
|
|
||||||
/// <summary>Unit Test for the Variegator multi dictionary</summary>
|
/// <summary>Unit Test for the Variegator multi dictionary</summary>
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class VariegatorTest {
|
internal class VariegatorTest {
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tests whether the default constructor of the reverse comparer works
|
/// Tests whether the default constructor of the reverse comparer works
|
||||||
|
|
|
@ -20,7 +20,6 @@ License along with this library
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace Nuclex.Support.Collections {
|
namespace Nuclex.Support.Collections {
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,11 @@ namespace Nuclex.Support {
|
||||||
|
|
||||||
/// <summary>Unit Test for the FloatHelper class</summary>
|
/// <summary>Unit Test for the FloatHelper class</summary>
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
internal class FloatHelperTest {
|
public class FloatHelperTest {
|
||||||
|
|
||||||
/// <summary>Tests the floating point value comparison helper</summary>
|
/// <summary>Tests the floating point value comparison helper</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestFloatComparison() {
|
public void UlpDistancesOnFloatsCompareAsEqual() {
|
||||||
Assert.IsTrue(
|
Assert.IsTrue(
|
||||||
FloatHelper.AreAlmostEqual(0.00000001f, 0.0000000100000008f, 1),
|
FloatHelper.AreAlmostEqual(0.00000001f, 0.0000000100000008f, 1),
|
||||||
"Minimal difference between very small floating point numbers is considered equal"
|
"Minimal difference between very small floating point numbers is considered equal"
|
||||||
|
@ -55,7 +55,7 @@ namespace Nuclex.Support {
|
||||||
|
|
||||||
/// <summary>Tests the double precision floating point value comparison helper</summary>
|
/// <summary>Tests the double precision floating point value comparison helper</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestDoubleComparison() {
|
public void UlpDistancesOnDoublesCompareAsEqual() {
|
||||||
Assert.IsTrue(
|
Assert.IsTrue(
|
||||||
FloatHelper.AreAlmostEqual(0.00000001, 0.000000010000000000000002, 1),
|
FloatHelper.AreAlmostEqual(0.00000001, 0.000000010000000000000002, 1),
|
||||||
"Minimal difference between very small double precision floating point " +
|
"Minimal difference between very small double precision floating point " +
|
||||||
|
@ -81,7 +81,7 @@ namespace Nuclex.Support {
|
||||||
|
|
||||||
/// <summary>Tests the integer reinterpretation functions</summary>
|
/// <summary>Tests the integer reinterpretation functions</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestIntegerReinterpretation() {
|
public void IntegersCanBeReinterpretedAsFloats() {
|
||||||
Assert.AreEqual(
|
Assert.AreEqual(
|
||||||
12345.0f,
|
12345.0f,
|
||||||
FloatHelper.ReinterpretAsFloat(FloatHelper.ReinterpretAsInt(12345.0f)),
|
FloatHelper.ReinterpretAsFloat(FloatHelper.ReinterpretAsInt(12345.0f)),
|
||||||
|
@ -91,7 +91,7 @@ namespace Nuclex.Support {
|
||||||
|
|
||||||
/// <summary>Tests the long reinterpretation functions</summary>
|
/// <summary>Tests the long reinterpretation functions</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestLongReinterpretation() {
|
public void LongsCanBeReinterpretedAsDoubles() {
|
||||||
Assert.AreEqual(
|
Assert.AreEqual(
|
||||||
12345.67890,
|
12345.67890,
|
||||||
FloatHelper.ReinterpretAsDouble(FloatHelper.ReinterpretAsLong(12345.67890)),
|
FloatHelper.ReinterpretAsDouble(FloatHelper.ReinterpretAsLong(12345.67890)),
|
||||||
|
@ -101,7 +101,7 @@ namespace Nuclex.Support {
|
||||||
|
|
||||||
/// <summary>Tests the floating point reinterpretation functions</summary>
|
/// <summary>Tests the floating point reinterpretation functions</summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestFloatReinterpretation() {
|
public void FloatsCanBeReinterpretedAsIntegers() {
|
||||||
Assert.AreEqual(
|
Assert.AreEqual(
|
||||||
12345,
|
12345,
|
||||||
FloatHelper.ReinterpretAsInt(FloatHelper.ReinterpretAsFloat(12345)),
|
FloatHelper.ReinterpretAsInt(FloatHelper.ReinterpretAsFloat(12345)),
|
||||||
|
@ -109,12 +109,33 @@ namespace Nuclex.Support {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies that the IsZero() method can distinguish zero from very small values
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void CanDetermineIfFloatIsZero() {
|
||||||
|
Assert.IsTrue(FloatHelper.IsZero(FloatHelper.PositiveZeroFloat));
|
||||||
|
Assert.IsTrue(FloatHelper.IsZero(FloatHelper.NegativeZeroFloat));
|
||||||
|
Assert.IsFalse(FloatHelper.IsZero(1.401298E-45f));
|
||||||
|
Assert.IsFalse(FloatHelper.IsZero(-1.401298E-45f));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Verifies that the IsZero() method can distinguish zero from very small values
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void CanDetermineIfDoubleIsZero() {
|
||||||
|
Assert.IsTrue(FloatHelper.IsZero(FloatHelper.PositiveZeroDouble));
|
||||||
|
Assert.IsTrue(FloatHelper.IsZero(FloatHelper.NegativeZeroDouble));
|
||||||
|
Assert.IsFalse(FloatHelper.IsZero(4.94065645841247E-324));
|
||||||
|
Assert.IsFalse(FloatHelper.IsZero(-4.94065645841247E-324));
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Tests the double prevision floating point reinterpretation functions
|
/// Tests the double prevision floating point reinterpretation functions
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Test]
|
[Test]
|
||||||
public void TestDoubleReinterpretation() {
|
public void DoublesCanBeReinterpretedAsLongs() {
|
||||||
Assert.AreEqual(
|
Assert.AreEqual(
|
||||||
1234567890,
|
1234567890,
|
||||||
FloatHelper.ReinterpretAsLong(FloatHelper.ReinterpretAsDouble(1234567890)),
|
FloatHelper.ReinterpretAsLong(FloatHelper.ReinterpretAsDouble(1234567890)),
|
||||||
|
@ -122,6 +143,26 @@ namespace Nuclex.Support {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// http://www.altdevblogaday.com/2012/02/22/comparing-floating-point-numbers-2012-edition/
|
||||||
|
// Make both positive
|
||||||
|
// If both are negative -> fine
|
||||||
|
// If both are positive -> fine
|
||||||
|
// If different -> Measure both distances to zero in ulps and sum them
|
||||||
|
public void NegativeZeroEqualsPositiveZero() {
|
||||||
|
float zero = 0.0f;
|
||||||
|
float zeroPlusOneUlp = FloatHelper.ReinterpretAsFloat(
|
||||||
|
FloatHelper.ReinterpretAsInt(zero) + 1
|
||||||
|
);
|
||||||
|
float zeroMinusOneUlp = -zeroPlusOneUlp;
|
||||||
|
|
||||||
|
bool test = FloatHelper.AreAlmostEqual(zeroMinusOneUlp, zeroPlusOneUlp, 1);
|
||||||
|
|
||||||
|
Assert.IsFalse(FloatHelper.AreAlmostEqual(zero, zeroPlusOneUlp, 0));
|
||||||
|
Assert.IsTrue(FloatHelper.AreAlmostEqual(zero, zeroPlusOneUlp, 1));
|
||||||
|
Assert.IsFalse(FloatHelper.AreAlmostEqual(zero, zeroMinusOneUlp, 0));
|
||||||
|
Assert.IsTrue(FloatHelper.AreAlmostEqual(zero, zeroMinusOneUlp, 1));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Nuclex.Support
|
} // namespace Nuclex.Support
|
||||||
|
|
|
@ -88,6 +88,40 @@ namespace Nuclex.Support {
|
||||||
|
|
||||||
#endregion // struct DoubleLongUnion
|
#endregion // struct DoubleLongUnion
|
||||||
|
|
||||||
|
/// <summary>A floating point value that holds a positive zero</summary>
|
||||||
|
public const float PositiveZeroFloat = +0.0f;
|
||||||
|
|
||||||
|
/// <summary>A floating point value that holds a negative zero</summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Negative zeros have a special representation in IEEE 752 floating point math
|
||||||
|
/// </remarks>
|
||||||
|
public const float NegativeZeroFloat = -0.0f;
|
||||||
|
|
||||||
|
/// <summary>A double precision floating point value that holds a positive zero</summary>
|
||||||
|
public const double PositiveZeroDouble = +0.0;
|
||||||
|
|
||||||
|
/// <summary>A doublep precision floating point value that holds a negative zero</summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Negative zeros have a special representation in IEEE 752 floating point math
|
||||||
|
/// </remarks>
|
||||||
|
public const double NegativeZeroDouble = -0.0;
|
||||||
|
|
||||||
|
/// <summary>Checks whether the floating point value is exactly zero</summary>
|
||||||
|
/// <param name="value">Value that will be checked for being zero</param>
|
||||||
|
/// <returns>True if the value is zero, false otherwise</returns>
|
||||||
|
public static bool IsZero(float value) {
|
||||||
|
return (value == PositiveZeroFloat) || (value == NegativeZeroFloat);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks whether the double precision floating point value is exactly zero
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">Value that will be checked for being zero</param>
|
||||||
|
/// <returns>True if the value is zero, false otherwise</returns>
|
||||||
|
public static bool IsZero(double value) {
|
||||||
|
return (value == PositiveZeroDouble) || (value == NegativeZeroDouble);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>Compares two floating point values for equality</summary>
|
/// <summary>Compares two floating point values for equality</summary>
|
||||||
/// <param name="left">First floating point value to be compared</param>
|
/// <param name="left">First floating point value to be compared</param>
|
||||||
/// <param name="right">Second floating point value t be compared</param>
|
/// <param name="right">Second floating point value t be compared</param>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user