From 395f145ba0c220afb1d85ff8c26f34909d8ea424 Mon Sep 17 00:00:00 2001 From: Han Lee Date: Wed, 14 Jun 2017 09:14:18 -0700 Subject: [PATCH] Fix a COMDouble::Round() issue (#12210) * 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 --- src/classlibnative/float/floatdouble.cpp | 5 +-- src/classlibnative/float/floatsingle.cpp | 5 +-- .../src/CoreMangLib/cti/system/math/mathround3.cs | 44 ++++++++++++++++++++++ 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/classlibnative/float/floatdouble.cpp b/src/classlibnative/float/floatdouble.cpp index 6f593e5..ba90a57 100644 --- a/src/classlibnative/float/floatdouble.cpp +++ b/src/classlibnative/float/floatdouble.cpp @@ -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; } diff --git a/src/classlibnative/float/floatsingle.cpp b/src/classlibnative/float/floatsingle.cpp index c7b7d41..ba48aea 100644 --- a/src/classlibnative/float/floatsingle.cpp +++ b/src/classlibnative/float/floatsingle.cpp @@ -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; } diff --git a/tests/src/CoreMangLib/cti/system/math/mathround3.cs b/tests/src/CoreMangLib/cti/system/math/mathround3.cs index b48766d..c4b4f69 100644 --- a/tests/src/CoreMangLib/cti/system/math/mathround3.cs +++ b/tests/src/CoreMangLib/cti/system/math/mathround3.cs @@ -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 -- 2.7.4