[Libreoffice-commits] core.git: sal/qa sal/rtl

Stephan Bergmann (via logerrit) logerrit at kemper.freedesktop.org
Thu Jul 8 13:32:57 UTC 2021


 sal/qa/rtl/math/test-rtl-math.cxx |   16 ++++++++++++++++
 sal/rtl/math.cxx                  |    4 ++--
 2 files changed, 18 insertions(+), 2 deletions(-)

New commits:
commit 2b2b6405161025678f91a5625e50d0b414597368
Author:     Stephan Bergmann <sbergman at redhat.com>
AuthorDate: Thu Jul 8 10:46:46 2021 +0200
Commit:     Stephan Bergmann <sbergman at redhat.com>
CommitDate: Thu Jul 8 15:32:19 2021 +0200

    Reliably generate positive or negative NaN again
    
    ...after e5c80bb69a30dfb0a3daf6061ab127d92f8142d6 "Purge out setNan from
    math.cxx" had dropped the use of rtl::math::setNan and sign bit fiddling, and
    relied on the implicit assumption that std::numeric_limits<double>::quiet_NaN
    would produce a positive NaN (but which does not seem to be guaranteed by the
    C++ standard) and on the expressed hope that multiplying such a positive NaN by
    -1 would generate a negative NaN (but which does not seem to be guaranteed by
    IEEE 754: while it mandates that a NaN's payload is preserved across such an
    operation, the result's sign bit appears to be unspecified)
    
    Change-Id: I12215c888a1cb8de6b3f046a836c550cb21b5a85
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118604
    Tested-by: Jenkins
    Reviewed-by: Stephan Bergmann <sbergman at redhat.com>

diff --git a/sal/qa/rtl/math/test-rtl-math.cxx b/sal/qa/rtl/math/test-rtl-math.cxx
index d5bbac1a684e..f4df71e78ac3 100644
--- a/sal/qa/rtl/math/test-rtl-math.cxx
+++ b/sal/qa/rtl/math/test-rtl-math.cxx
@@ -74,6 +74,22 @@ public:
         CPPUNIT_ASSERT_EQUAL(sal_Int32(3), end);
         CPPUNIT_ASSERT(std::isnan(res));
 
+        res = rtl::math::stringToDouble(
+                OUString("+1.#NAN"),
+                '.', ',', &status, &end);
+        CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(7), end);
+        CPPUNIT_ASSERT(std::isnan(res));
+        CPPUNIT_ASSERT(!std::signbit(res));
+
+        res = rtl::math::stringToDouble(
+                OUString("-1.#NAN"),
+                '.', ',', &status, &end);
+        CPPUNIT_ASSERT_EQUAL(rtl_math_ConversionStatus_Ok, status);
+        CPPUNIT_ASSERT_EQUAL(sal_Int32(7), end);
+        CPPUNIT_ASSERT(std::isnan(res));
+        CPPUNIT_ASSERT(std::signbit(res));
+
         res = rtl::math::stringToDouble(
                 OUString("INF"),
                 '.', ',', &status, &end);
diff --git a/sal/rtl/math.cxx b/sal/rtl/math.cxx
index e9b50a1b4638..5d4ed6061f97 100644
--- a/sal/rtl/math.cxx
+++ b/sal/rtl/math.cxx
@@ -1004,8 +1004,8 @@ double stringToDouble(CharT const * pBegin, CharT const * pEnd,
             {
                 // "1.#NAN", "+1.#NAN", "-1.#NAN"
                 p += 4;
-                fVal = std::numeric_limits<double>::quiet_NaN();
-                // bSign will cause negation of fVal in the end, producing a negative NAN.
+                fVal = std::copysign(std::numeric_limits<double>::quiet_NaN(), bSign ? -1.0 : 1.0);
+                bSign = false; // don't negate again
 
                 // Eat any further digits:
                 while (p != pEnd && rtl::isAsciiDigit(*p))


More information about the Libreoffice-commits mailing list