Fix a COMDouble::Round() issue (dotnet/coreclr#12210)
authorHan Lee <han.lee@intel.com>
Wed, 14 Jun 2017 16:14:18 +0000 (09:14 -0700)
committerJan Vorlicek <janvorli@microsoft.com>
Wed, 14 Jun 2017 16:14:18 +0000 (18:14 +0200)
* Fix a COMDouble::Round() issue
fixes https://github.com/dotnet/coreclr/issues/12137

* Add a couple tests for Math.Round(double)
based on https://github.com/dotnet/coreclr/issues/12137

* Use G17 format specifier for printing double values

Commit migrated from https://github.com/dotnet/coreclr/commit/395f145ba0c220afb1d85ff8c26f34909d8ea424

src/coreclr/src/classlibnative/float/floatdouble.cpp
src/coreclr/src/classlibnative/float/floatsingle.cpp
src/coreclr/tests/src/CoreMangLib/cti/system/math/mathround3.cs

index 6f593e5..ba90a57 100644 (file)
@@ -183,10 +183,9 @@ FCIMPL1_V(double, COMDouble::Round, double x)
     // We had a number that was equally close to 2 integers.
     // We need to return the even one.
 
-    double tempVal = (x + 0.5);
-    double flrTempVal = floor(tempVal);
+    double flrTempVal = floor(x + 0.5);
 
-    if ((flrTempVal == tempVal) && (fmod(tempVal, 2.0) != 0)) {
+    if ((x == (floor(x) + 0.5)) && (fmod(flrTempVal, 2.0) != 0)) {
         flrTempVal -= 1.0;
     }
 
index c7b7d41..ba48aea 100644 (file)
@@ -181,10 +181,9 @@ FCIMPL1_V(float, COMSingle::Round, float x)
     // We had a number that was equally close to 2 integers.
     // We need to return the even one.
 
-    float tempVal = (x + 0.5f);
-    float flrTempVal = floorf(tempVal);
+    float flrTempVal = floorf(x + 0.5f);
 
-    if ((flrTempVal == tempVal) && (fmodf(tempVal, 2.0f) != 0)) {
+    if ((x == (floorf(x) + 0.5f)) && (fmod(flrTempVal, 2.0f) != 0)) {
         flrTempVal -= 1.0f;
     }
 
index b48766d..c4b4f69 100644 (file)
@@ -13,6 +13,8 @@ public class MathRound3
         TestLibrary.TestFramework.LogInformation("[Positive]");
         retVal = PosTest1() && retVal;
         retVal = PosTest2() && retVal;
+        retVal = PosTest3() && retVal;
+        retVal = PosTest4() && retVal;
 
         retVal = NegTest1() && retVal;
 
@@ -91,6 +93,48 @@ public class MathRound3
 
         return retVal;
     }
+
+    public bool PosTest3()
+    {
+        bool retVal = true;
+
+        // Test based on https://github.com/dotnet/coreclr/issues/12137
+        TestLibrary.TestFramework.BeginScenario("PosTest3: Verify Round(System.double) when decimal part of arg is very close to -0.5 .");
+
+        double doubleVal = -.50000000000000011102230246251565404236316680908203;
+        double expectedVal = -1.0;
+            
+        if (Math.Round(doubleVal) != expectedVal)
+        {
+            Console.WriteLine("actual value = {0:G17}", Math.Round(doubleVal));
+            Console.WriteLine("expected value = {0:G17}", expectedVal);
+            TestLibrary.TestFramework.LogError("001.1", "Return value is wrong!");
+            retVal = false;
+        }
+        
+        return retVal;    
+    }
+
+    public bool PosTest4()
+    {
+        bool retVal = true;
+
+        // Test based on https://github.com/dotnet/coreclr/issues/12137
+        TestLibrary.TestFramework.BeginScenario("PosTest4: Verify Round(System.double) when decimal part of arg is very close to 0.5 .");
+
+        double doubleVal = 0.50000000000000011102230246251565404236316680908203;
+        double expectedVal = 1.0;
+
+        if (Math.Round(doubleVal) != expectedVal)
+        {
+            Console.WriteLine("actual value = {0:G17}", Math.Round(doubleVal));
+            Console.WriteLine("expected value = {0:G17}", expectedVal);
+            TestLibrary.TestFramework.LogError("001.1", "Return value is wrong!");
+            retVal = false;
+        }
+
+        return retVal;    
+    }
     #endregion
 
     #region Nagetive Test Cases