diff --git a/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs b/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs
index f45b88c9478d4..32dd05facb031 100644
--- a/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs
+++ b/src/libraries/Common/tests/TestUtilities/System/AssertExtensions.cs
@@ -663,6 +663,126 @@ public ItemCount(int original, int remain)
}
}
+ static unsafe bool IsNegativeZero(float value)
+ {
+ return (*(uint*)(&value)) == 0x80000000;
+ }
+
+ static unsafe bool IsPositiveZero(float value)
+ {
+ return (*(uint*)(&value)) == 0x00000000;
+ }
+
+ static unsafe bool IsNegativeZero(double value)
+ {
+ return (*(ulong*)(&value)) == 0x8000000000000000;
+ }
+
+ static unsafe bool IsPositiveZero(double value)
+ {
+ return (*(ulong*)(&value)) == 0x0000000000000000;
+ }
+
+#if NET6_0_OR_GREATER
+ static unsafe bool IsNegativeZero(Half value)
+ {
+ return (*(ushort*)(&value)) == 0x8000;
+ }
+
+ static unsafe bool IsPositiveZero(Half value)
+ {
+ return (*(ushort*)(&value)) == 0x0000;
+ }
+#endif
+
+ // We have a custom ToString here to ensure that edge cases (specifically +-0.0,
+ // but also NaN and +-infinity) are correctly and consistently represented.
+ static string ToStringPadded(float value)
+ {
+ if (float.IsNaN(value))
+ {
+ return "NaN".PadLeft(10);
+ }
+ else if (float.IsPositiveInfinity(value))
+ {
+ return "+\u221E".PadLeft(10);
+ }
+ else if (float.IsNegativeInfinity(value))
+ {
+ return "-\u221E".PadLeft(10);
+ }
+ else if (IsNegativeZero(value))
+ {
+ return "-0.0".PadLeft(10);
+ }
+ else if (IsPositiveZero(value))
+ {
+ return "+0.0".PadLeft(10);
+ }
+ else
+ {
+ return $"{value,10:G9}";
+ }
+ }
+
+ static string ToStringPadded(double value)
+ {
+ if (double.IsNaN(value))
+ {
+ return "NaN".PadLeft(20);
+ }
+ else if (double.IsPositiveInfinity(value))
+ {
+ return "+\u221E".PadLeft(20);
+ }
+ else if (double.IsNegativeInfinity(value))
+ {
+ return "-\u221E".PadLeft(20);
+ }
+ else if (IsNegativeZero(value))
+ {
+ return "-0.0".PadLeft(20);
+ }
+ else if (IsPositiveZero(value))
+ {
+ return "+0.0".PadLeft(20);
+ }
+ else
+ {
+ return $"{value,20:G17}";
+ }
+ }
+
+#if NET6_0_OR_GREATER
+ static string ToStringPadded(Half value)
+ {
+ if (Half.IsNaN(value))
+ {
+ return "NaN".PadLeft(5);
+ }
+ else if (Half.IsPositiveInfinity(value))
+ {
+ return "+\u221E".PadLeft(5);
+ }
+ else if (Half.IsNegativeInfinity(value))
+ {
+ return "-\u221E".PadLeft(5);
+ }
+ else if (IsNegativeZero(value))
+ {
+ return "-0.0".PadLeft(5);
+ }
+ else if (IsPositiveZero(value))
+ {
+ return "+0.0".PadLeft(5);
+ }
+ else
+ {
+ return $"{value,5:G5}";
+ }
+ }
+#endif
+
/// Verifies that two values are equal, within the .
/// The expected value
/// The value to be compared against
@@ -774,46 +894,6 @@ public static void Equal(double expected, double actual, double variance)
{
throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual));
}
-
- static unsafe bool IsNegativeZero(double value)
- {
- return (*(ulong*)(&value)) == 0x8000000000000000;
- }
-
- static unsafe bool IsPositiveZero(double value)
- {
- return (*(ulong*)(&value)) == 0x0000000000000000;
- }
-
- // We have a custom ToString here to ensure that edge cases (specifically +-0.0,
- // but also NaN and +-infinity) are correctly and consistently represented.
- static string ToStringPadded(double value)
- {
- if (double.IsNaN(value))
- {
- return "NaN".PadLeft(20);
- }
- else if (double.IsPositiveInfinity(value))
- {
- return "+\u221E".PadLeft(20);
- }
- else if (double.IsNegativeInfinity(value))
- {
- return "-\u221E".PadLeft(20);
- }
- else if (IsNegativeZero(value))
- {
- return "-0.0".PadLeft(20);
- }
- else if (IsPositiveZero(value))
- {
- return "+0.0".PadLeft(20);
- }
- else
- {
- return $"{value,20:G17}";
- }
- }
}
/// Verifies that two values are equal, within the .
@@ -927,46 +1007,6 @@ public static void Equal(float expected, float actual, float variance)
{
throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual));
}
-
- static unsafe bool IsNegativeZero(float value)
- {
- return (*(uint*)(&value)) == 0x80000000;
- }
-
- static unsafe bool IsPositiveZero(float value)
- {
- return (*(uint*)(&value)) == 0x00000000;
- }
-
- // We have a custom ToString here to ensure that edge cases (specifically +-0.0,
- // but also NaN and +-infinity) are correctly and consistently represented.
- static string ToStringPadded(float value)
- {
- if (float.IsNaN(value))
- {
- return "NaN".PadLeft(10);
- }
- else if (float.IsPositiveInfinity(value))
- {
- return "+\u221E".PadLeft(10);
- }
- else if (float.IsNegativeInfinity(value))
- {
- return "-\u221E".PadLeft(10);
- }
- else if (IsNegativeZero(value))
- {
- return "-0.0".PadLeft(10);
- }
- else if (IsPositiveZero(value))
- {
- return "+0.0".PadLeft(10);
- }
- else
- {
- return $"{value,10:G9}";
- }
- }
}
#if NET6_0_OR_GREATER
@@ -1081,46 +1121,73 @@ public static void Equal(Half expected, Half actual, Half variance)
{
throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual));
}
+ }
+#endif
- static unsafe bool IsNegativeZero(Half value)
+ /// Verifies that two values's binary representations are identical.
+ /// The expected value
+ /// The value to be compared against
+ /// Thrown when the representations are not identical
+ public static void Equal(double expected, double actual)
+ {
+ if (BitConverter.DoubleToInt64Bits(expected) == BitConverter.DoubleToInt64Bits(actual))
{
- return (*(ushort*)(&value)) == 0x8000;
+ return;
}
- static unsafe bool IsPositiveZero(Half value)
+ if (PlatformDetection.IsRiscV64Process && double.IsNaN(expected) && double.IsNaN(actual))
{
- return (*(ushort*)(&value)) == 0x0000;
+ // RISC-V does not preserve payload
+ return;
}
- // We have a custom ToString here to ensure that edge cases (specifically +-0.0,
- // but also NaN and +-infinity) are correctly and consistently represented.
- static string ToStringPadded(Half value)
+ throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual));
+ }
+
+ /// Verifies that two values's binary representations are identical.
+ /// The expected value
+ /// The value to be compared against
+ /// Thrown when the representations are not identical
+ public static void Equal(float expected, float actual)
+ {
+ static unsafe int SingleToInt32Bits(float value)
{
- if (Half.IsNaN(value))
- {
- return "NaN".PadLeft(5);
- }
- else if (Half.IsPositiveInfinity(value))
- {
- return "+\u221E".PadLeft(5);
- }
- else if (Half.IsNegativeInfinity(value))
- {
- return "-\u221E".PadLeft(5);
- }
- else if (IsNegativeZero(value))
- {
- return "-0.0".PadLeft(5);
- }
- else if (IsPositiveZero(value))
- {
- return "+0.0".PadLeft(5);
- }
- else
- {
- return $"{value,5:G5}";
- }
+ return *(int*)&value;
+ }
+
+ if (SingleToInt32Bits(expected) == SingleToInt32Bits(actual))
+ {
+ return;
+ }
+
+ if (PlatformDetection.IsRiscV64Process && float.IsNaN(expected) && float.IsNaN(actual))
+ {
+ // RISC-V does not preserve payload
+ return;
+ }
+
+ throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual));
+ }
+
+#if NET6_0_OR_GREATER
+ /// Verifies that two values's binary representations are identical.
+ /// The expected value
+ /// The value to be compared against
+ /// Thrown when the representations are not identical
+ public static void Equal(Half expected, Half actual)
+ {
+ if (BitConverter.HalfToInt16Bits(expected) == BitConverter.HalfToInt16Bits(actual))
+ {
+ return;
}
+
+ if (PlatformDetection.IsRiscV64Process && Half.IsNaN(expected) && Half.IsNaN(actual))
+ {
+ // RISC-V does not preserve payload
+ return;
+ }
+
+ throw EqualException.ForMismatchedValues(ToStringPadded(expected), ToStringPadded(actual));
}
#endif
}
diff --git a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/HalfTests.cs b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/HalfTests.cs
index 1e7f06602c0ec..600326b39d85f 100644
--- a/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/HalfTests.cs
+++ b/src/libraries/System.Runtime/tests/System.Runtime.Tests/System/HalfTests.cs
@@ -411,7 +411,7 @@ public static IEnumerable