On Wed, 7 Jun 2023 at 18:26, Jonathan Wakely <jwakely....@gmail.com> wrote:
> > > On Wed, 7 Jun 2023, 18:17 Jakub Jelinek via Libstdc++, < > libstd...@gcc.gnu.org> wrote: > >> Hi! >> >> 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. >> >> Bootstrapped/regtested on x86_64-linux and i686-linux, additionally >> tested on the latter with >> make check RUNTESTFLAGS='--target_board=unix/-fexcess-precision=standard >> conformance.exp=to_chars/double.cc' >> Ok for trunk? >> > > Yes, OK. > > Thanks for solving this puzzle! > I think this would be good for gcc-13, as that has the new -fexcess-precision semantics for -std=c++NN too, right? > > > >> 2023-06-07 Jakub Jelinek <ja...@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. >> >> --- libstdc++-v3/testsuite/20_util/to_chars/double.cc.jj >> 2022-11-03 22:16:08.542329555 +0100 >> +++ libstdc++-v3/testsuite/20_util/to_chars/double.cc 2023-06-07 >> 15:41:44.275604870 +0200 >> @@ -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_testcas >> {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_testcas >> {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_testcas >> "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_testcas >> {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"}, >> >> Jakub >> >>