public inbox for libstdc++-cvs@sourceware.org help / color / mirror / Atom feed
From: Giuliano Belinassi <giulianob@gcc.gnu.org> To: gcc-cvs@gcc.gnu.org, libstdc++-cvs@gcc.gnu.org Subject: [gcc(refs/users/giulianob/heads/autopar_rebase2)] libstdc++: Make std::from_chars always round to nearest Date: Tue, 18 Aug 2020 01:12:29 +0000 (GMT) [thread overview] Message-ID: <20200818011229.8E54A388C02B@sourceware.org> (raw) https://gcc.gnu.org/g:b583d3f8d6ad3c26f8efc5d7dbee9f9969a593a0 commit b583d3f8d6ad3c26f8efc5d7dbee9f9969a593a0 Author: Jonathan Wakely <jwakely@redhat.com> Date: Mon Jul 27 15:51:16 2020 +0100 libstdc++: Make std::from_chars always round to nearest Also fix the tests that fail on targets without uselocale. libstdc++-v3/ChangeLog: * src/c++17/floating_from_chars.cc (from_chars_impl): Ensure that FE_NEAREST is used. * testsuite/20_util/from_chars/4.cc: Do not use if constexpr in a { target c++14 } test. [!_GLIBCXX_HAVE_USELOCALE]: Disable all tests. * testsuite/20_util/from_chars/5.cc [!_GLIBCXX_HAVE_USELOCALE]: Likewise. * testsuite/20_util/from_chars/6.cc: New test. Diff: --- libstdc++-v3/src/c++17/floating_from_chars.cc | 12 +++++++ libstdc++-v3/testsuite/20_util/from_chars/4.cc | 9 +++-- libstdc++-v3/testsuite/20_util/from_chars/5.cc | 6 ++++ libstdc++-v3/testsuite/20_util/from_chars/6.cc | 49 ++++++++++++++++++++++++++ 4 files changed, 74 insertions(+), 2 deletions(-) diff --git a/libstdc++-v3/src/c++17/floating_from_chars.cc b/libstdc++-v3/src/c++17/floating_from_chars.cc index 45de2be283d..f1519e5c7b6 100644 --- a/libstdc++-v3/src/c++17/floating_from_chars.cc +++ b/libstdc++-v3/src/c++17/floating_from_chars.cc @@ -30,6 +30,7 @@ #include <charconv> #include <string> #include <memory_resource> +#include <cfenv> #include <cmath> #include <cstdlib> #include <cstring> @@ -289,6 +290,12 @@ namespace { locale_t orig = ::uselocale(loc); +#if _GLIBCXX_USE_C99_FENV_TR1 + const int rounding = std::fegetround(); + if (rounding != FE_TONEAREST) + std::fesetround(FE_TONEAREST); +#endif + const int save_errno = errno; errno = 0; char* endptr; @@ -301,6 +308,11 @@ namespace tmpval = std::strtold(str, &endptr); const int conv_errno = std::__exchange(errno, save_errno); +#if _GLIBCXX_USE_C99_FENV_TR1 + if (rounding != FE_TONEAREST) + std::fesetround(rounding); +#endif + ::uselocale(orig); ::freelocale(loc); diff --git a/libstdc++-v3/testsuite/20_util/from_chars/4.cc b/libstdc++-v3/testsuite/20_util/from_chars/4.cc index 6d692592e95..e7127ed0c48 100644 --- a/libstdc++-v3/testsuite/20_util/from_chars/4.cc +++ b/libstdc++-v3/testsuite/20_util/from_chars/4.cc @@ -27,6 +27,9 @@ // Test std::from_chars floating-point conversions. +// As of July 2020 __cpp_lib_to_chars is not defined, but std::from_chars +// works for floating-point types when _GLIBCXX_HAVE_USELOCALE is defined. +#if __cpp_lib_to_chars >= 201611L || _GLIBCXX_HAVE_USELOCALE void test01() { @@ -296,8 +299,7 @@ test_max_mantissa() using Float_limits = std::numeric_limits<FloatT>; using UInt_limits = std::numeric_limits<UIntT>; - if constexpr (Float_limits::is_iec559 - && Float_limits::digits < UInt_limits::digits) + if (Float_limits::is_iec559 && Float_limits::digits < UInt_limits::digits) { std::printf("Testing %d-bit float, using %zu-bit integer\n", Float_limits::digits + (int)std::log2(Float_limits::max_exponent) + 1, @@ -355,14 +357,17 @@ test06() test_max_mantissa<long double, unsigned __GLIBCXX_TYPE_INT_N_0>(); #endif } +#endif int main() { +#if __cpp_lib_to_chars >= 201611L || _GLIBCXX_HAVE_USELOCALE test01(); test02(); test03(); test04(); test05(); test06(); +#endif } diff --git a/libstdc++-v3/testsuite/20_util/from_chars/5.cc b/libstdc++-v3/testsuite/20_util/from_chars/5.cc index f8fc7f6cd12..9525da8aebe 100644 --- a/libstdc++-v3/testsuite/20_util/from_chars/5.cc +++ b/libstdc++-v3/testsuite/20_util/from_chars/5.cc @@ -25,6 +25,9 @@ // Test std::from_chars error handling. +// As of July 2020 __cpp_lib_to_chars is not defined, but std::from_chars +// works for floating-point types when _GLIBCXX_HAVE_USELOCALE is defined. +#if __cpp_lib_to_chars >= 201611L || _GLIBCXX_HAVE_USELOCALE void test01() { @@ -152,12 +155,15 @@ test04() } } } +#endif int main() { +#if __cpp_lib_to_chars >= 201611L || _GLIBCXX_HAVE_USELOCALE test01(); test02(); test03(); test04(); +#endif } diff --git a/libstdc++-v3/testsuite/20_util/from_chars/6.cc b/libstdc++-v3/testsuite/20_util/from_chars/6.cc new file mode 100644 index 00000000000..e592b2eb806 --- /dev/null +++ b/libstdc++-v3/testsuite/20_util/from_chars/6.cc @@ -0,0 +1,49 @@ +// Copyright (C) 2020 Free Software Foundation, Inc. +// +// This file is part of the GNU ISO C++ Library. This library is free +// software; you can redistribute it and/or modify it under the +// terms of the GNU General Public License as published by the +// Free Software Foundation; either version 3, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// <http://www.gnu.org/licenses/>. + +// <charconv> is supported in C++14 as a GNU extension +// { dg-do run { target c++14 } } +// { dg-add-options ieee } + +#include <charconv> +#include <string> +#include <cfenv> +#include <testsuite_hooks.h> + +void +test01() +{ +#if __cpp_lib_to_chars >= 201611L || _GLIBCXX_HAVE_USELOCALE +#if _GLIBCXX_USE_C99_FENV_TR1 + double d; + std::fesetround(FE_DOWNWARD); + const std::string s = "0.099999999999999999999999999"; + auto res = std::from_chars(s.data(), s.data() + s.length(), d); + VERIFY( res.ec == std::errc{} ); + VERIFY( res.ptr == s.data() + s.length() ); + // std::from_chars should ignore the current rounding mode + // and always round to nearest. + VERIFY( d == 0.1 ); +#endif +#endif +} + +int +main() +{ + test01(); +}
reply other threads:[~2020-08-18 1:12 UTC|newest] Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20200818011229.8E54A388C02B@sourceware.org \ --to=giulianob@gcc.gnu.org \ --cc=gcc-cvs@gcc.gnu.org \ --cc=libstdc++-cvs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
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).