public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-1619] libstdc++: Fix up 20_util/to_chars/double.cc test for excess precision [PR110145]
@ 2023-06-07 17:28 Jakub Jelinek
  0 siblings, 0 replies; only message in thread
From: Jakub Jelinek @ 2023-06-07 17:28 UTC (permalink / raw)
  To: gcc-cvs, libstdc++-cvs

https://gcc.gnu.org/g:88e7f1f7ee67462713a89104ae07e99b191d5e2c

commit r14-1619-g88e7f1f7ee67462713a89104ae07e99b191d5e2c
Author: Jakub Jelinek <jakub@redhat.com>
Date:   Wed Jun 7 19:27:35 2023 +0200

    libstdc++: Fix up 20_util/to_chars/double.cc test for excess precision [PR110145]
    
    This test apparently contains 3 problematic floating point constants,
    1e126, 4.91e-6 and 5.547e-6.  These constants suffer from double rounding
    when -fexcess-precision=standard evaluates double constants in the precision
    of Intel extended 80-bit long double.
    As written in the PR, e.g. the first one is
    0x1.7a2ecc414a03f7ff6ca1cb527787b130a97d51e51202365p+418
    in the precision of GCC's internal format, 80-bit long double has
    63-bit precision, so the above constant rounded to long double is
    0x1.7a2ecc414a03f800p+418L
    (the least significant bit in the 0 before p isn't there already).
    0x1.7a2ecc414a03f800p+418L rounded to IEEE double is
    0x1.7a2ecc414a040p+418.
    Now, if excess precision doesn't happen and we round the GCC's internal
    format number directly to double, it is
    0x1.7a2ecc414a03fp+418 and that is the number the test expects.
    One can see it on x86-64 (where excess precision to long double doesn't
    happen) where double(1e126L) != 1e126.
    The other two constants suffer from the same problem.
    
    The following patch tweaks the testcase, such that those problematic
    constants are used only if FLT_EVAL_METHOD is 0 or 1 (i.e. when we have
    guarantee the constants will be evaluated in double precision),
    plus adds corresponding tests with hexadecimal constants which don't
    suffer from this excess precision problem, they are exact in double
    and long double can hold all double values.
    
    2023-06-07  Jakub Jelinek  <jakub@redhat.com>
    
            PR libstdc++/110145
            * testsuite/20_util/to_chars/double.cc: Include <cfloat>.
            (double_to_chars_test_cases,
            double_scientific_precision_to_chars_test_cases_2,
            double_fixed_precision_to_chars_test_cases_2): #if out 1e126, 4.91e-6
            and 5.547e-6 tests if FLT_EVAL_METHOD is negative or larger than 1.
            Add unconditional tests with corresponding double constants
            0x1.7a2ecc414a03fp+418, 0x1.4981285e98e79p-18 and
            0x1.7440bbff418b9p-18.

Diff:
---
 libstdc++-v3/testsuite/20_util/to_chars/double.cc | 26 +++++++++++++++++++++++
 1 file changed, 26 insertions(+)

diff --git a/libstdc++-v3/testsuite/20_util/to_chars/double.cc b/libstdc++-v3/testsuite/20_util/to_chars/double.cc
index ac9a43099a2..38c7e4a3eed 100644
--- a/libstdc++-v3/testsuite/20_util/to_chars/double.cc
+++ b/libstdc++-v3/testsuite/20_util/to_chars/double.cc
@@ -40,6 +40,7 @@
 #include <cstring>
 #include <limits>
 #include <optional>
+#include <cfloat>
 
 #include <testsuite_hooks.h>
 
@@ -1968,9 +1969,19 @@ inline constexpr double_to_chars_testcase double_to_chars_test_cases[] = {
     {1e125, chars_format::fixed,
         "9999999999999999248677616189928820425446708698348384614392259722252941999757930266031634937628176537515300"
         "5841365553228283904"},
+#if FLT_EVAL_METHOD >= 0 && FLT_EVAL_METHOD <= 1
+    // When long double is Intel extended and double constants are evaluated in precision of
+    // long double, this value is initialized to double(1e126L), which is 0x1.7a2ecc414a040p+418 due to
+    // double rounding of 0x1.7a2ecc414a03f7ff6p+418L first to 0x1.7a2ecc414a03f800p+418L and
+    // then to 0x1.7a2ecc414a040p+418, while when double constants are evaluated in precision of
+    // IEEE double, this is 0x1.7a2ecc414a03fp+418 which the test expects.  See PR110145.
     {1e126, chars_format::fixed,
         "9999999999999999248677616189928820425446708698348384614392259722252941999757930266031634937628176537515300"
         "58413655532282839040"},
+#endif
+    {0x1.7a2ecc414a03fp+418, chars_format::fixed,
+	"9999999999999999248677616189928820425446708698348384614392259722252941999757930266031634937628176537515300"
+	"58413655532282839040"},
     {1e127, chars_format::fixed,
         "9999999999999999549291066784979473595300225087383524118479625982517885450291174622154390152298057300868772"
         "377386949310916067328"},
@@ -2816,8 +2827,12 @@ inline constexpr double_to_chars_testcase double_to_chars_test_cases[] = {
     {0x1.a6c767640cd71p+879, chars_format::scientific, "6.6564021122018745e+264"},
 
     // Incorrectly handled by dtoa_milo() (Grisu2), which doesn't achieve shortest round-trip.
+#if FLT_EVAL_METHOD >= 0 && FLT_EVAL_METHOD <= 1
     {4.91e-6, chars_format::scientific, "4.91e-06"},
     {5.547e-6, chars_format::scientific, "5.547e-06"},
+#endif
+    {0x1.4981285e98e79p-18, chars_format::scientific, "4.91e-06"},
+    {0x1.7440bbff418b9p-18, chars_format::scientific, "5.547e-06"},
 
     // Test hexfloat corner cases.
     {0x1.728p+0, chars_format::hex, "1.728p+0"}, // instead of "2.e5p-1"
@@ -5537,10 +5552,16 @@ inline constexpr double_to_chars_testcase double_scientific_precision_to_chars_t
         "9."
         "9999999999999992486776161899288204254467086983483846143922597222529419997579302660316349376281765375153005"
         "841365553228283904e+124"},
+#if FLT_EVAL_METHOD >= 0 && FLT_EVAL_METHOD <= 1
     {1e+126, chars_format::scientific, 124,
         "9."
         "9999999999999992486776161899288204254467086983483846143922597222529419997579302660316349376281765375153005"
         "841365553228283904e+125"},
+#endif
+    {0x1.7a2ecc414a03fp+418, chars_format::scientific, 124,
+	"9."
+	"9999999999999992486776161899288204254467086983483846143922597222529419997579302660316349376281765375153005"
+	"841365553228283904e+125"},
     {1e+127, chars_format::scientific, 126,
         "9."
         "9999999999999995492910667849794735953002250873835241184796259825178854502911746221543901522980573008687723"
@@ -29579,9 +29600,14 @@ inline constexpr double_to_chars_testcase double_fixed_precision_to_chars_test_c
     {1e+125, chars_format::fixed, 0,
         "9999999999999999248677616189928820425446708698348384614392259722252941999757930266031634937628176537515300"
         "5841365553228283904"},
+#if FLT_EVAL_METHOD >= 0 && FLT_EVAL_METHOD <= 1
     {1e+126, chars_format::fixed, 0,
         "9999999999999999248677616189928820425446708698348384614392259722252941999757930266031634937628176537515300"
         "58413655532282839040"},
+#endif
+    {0x1.7a2ecc414a03fp+418, chars_format::fixed, 0,
+	"9999999999999999248677616189928820425446708698348384614392259722252941999757930266031634937628176537515300"
+	"58413655532282839040"},
     {1e+127, chars_format::fixed, 0,
         "9999999999999999549291066784979473595300225087383524118479625982517885450291174622154390152298057300868772"
         "377386949310916067328"},

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-06-07 17:28 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-06-07 17:28 [gcc r14-1619] libstdc++: Fix up 20_util/to_chars/double.cc test for excess precision [PR110145] Jakub Jelinek

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).