Fix half equality method (#41259)
authorHuo Yaoyuan <huoyaoyuan@hotmail.com>
Mon, 24 Aug 2020 21:49:34 +0000 (05:49 +0800)
committerGitHub <noreply@github.com>
Mon, 24 Aug 2020 21:49:34 +0000 (14:49 -0700)
* Align Half.Equals implementation with Double.Equals.

* Add tests for new Half.Equals behaviour.

src/libraries/System.Private.CoreLib/src/System/Half.cs
src/libraries/System.Runtime/tests/System/HalfTests.cs

index 34adab5..1840f3c 100644 (file)
@@ -57,7 +57,7 @@ namespace System
 
         // Well-defined and commonly used values
 
-        public static Half Epsilon =>  new Half(EpsilonBits);                        //  5.9604645E-08
+        public static Half Epsilon => new Half(EpsilonBits);                        //  5.9604645E-08
 
         public static Half PositiveInfinity => new Half(PositiveInfinityBits);      //  1.0 / 0.0;
 
@@ -151,12 +151,19 @@ namespace System
 
         public static bool operator ==(Half left, Half right)
         {
-            return left.Equals(right);
+            if (IsNaN(left) || IsNaN(right))
+            {
+                // IEEE defines that NaN is not equal to anything, including itself.
+                return false;
+            }
+
+            // IEEE defines that positive and negative zero are equivalent.
+            return (left._value == right._value) || AreZero(left, right);
         }
 
         public static bool operator !=(Half left, Half right)
         {
-            return !(left.Equals(right));
+            return !(left == right);
         }
 
         /// <summary>Determines whether the specified value is finite (zero, subnormal, or normal).</summary>
@@ -415,14 +422,11 @@ namespace System
         /// </summary>
         public bool Equals(Half other)
         {
-            if (IsNaN(this) || IsNaN(other))
+            if (this == other)
             {
-                // IEEE defines that NaN is not equal to anything, including itself.
-                return false;
+                return true;
             }
-
-            // IEEE defines that positive and negative zero are equivalent.
-            return (_value == other._value) || AreZero(this, other);
+            return IsNaN(this) && IsNaN(other);
         }
 
         /// <summary>
index de5eddf..574c1ec 100644 (file)
@@ -335,7 +335,7 @@ namespace System.Tests
             yield return new object[] { Half.MaxValue, Half.MaxValue, true };
             yield return new object[] { Half.MaxValue, Half.MinValue, false };
             yield return new object[] { Half.MaxValue, UInt16BitsToHalf(0x0000), false };
-            yield return new object[] { Half.NaN, Half.NaN, false };
+            yield return new object[] { Half.NaN, Half.NaN, true };
             yield return new object[] { Half.MaxValue, 789.0f, false };
             yield return new object[] { Half.MaxValue, "789", false };
         }
@@ -932,5 +932,13 @@ namespace System.Tests
             float f = (float)half;
             Assert.Equal(f, verify, precision: 1);
         }
+
+        [Fact]
+        public static void EqualityMethodAndOperator()
+        {
+            Assert.True(Half.NaN.Equals(Half.NaN));
+            Assert.False(Half.NaN == Half.NaN);
+            Assert.Equal(Half.NaN, Half.NaN);
+        }
     }
 }