Message ID | 20230531122239.4116906-1-jwakely@redhat.com |
---|---|
State | New |
Headers | show |
Series | [committed] libstdc++: Add std::numeric_limits<__float128> specialization [PR104772] | expand |
On Wed, 31 May 2023 at 13:23, Jonathan Wakely via Libstdc++ < libstdc++@gcc.gnu.org> wrote: > Tested powerpc64le-linux. Pushed to trunk. > > -- >8 -- > > As suggested by Jakub in the PR, this just hardcodes the constants with > a Q suffix, since the properties of __float128 are not going to change. > > We can only define it for non-strict modes because the suffix gives an > error otherwise, even in system headers: > > limits:2085: error: unable to find numeric literal operator 'operator""Q' > > libstdc++-v3/ChangeLog: > > PR libstdc++/104772 > * include/std/limits (numeric_limits<__float128>): Define. > * testsuite/18_support/numeric_limits/128bit.cc: New test. > I should have tested this with clang before pushing: /home/jwakely/gcc/latest/lib/gcc/x86_64-pc-linux-gnu/14.0.0/../../../../include/c++/14.0.0/limits:2125: 16: error: use of undeclared identifier '__builtin_huge_valq' { return __builtin_huge_valq(); } ^ /home/jwakely/gcc/latest/lib/gcc/x86_64-pc-linux-gnu/14.0.0/../../../../include/c++/14.0.0/limits:2129: 16: error: use of undeclared identifier '__builtin_nanq' { return __builtin_nanq(""); } ^ /home/jwakely/gcc/latest/lib/gcc/x86_64-pc-linux-gnu/14.0.0/../../../../include/c++/14.0.0/limits:2133: 16: error: use of undeclared identifier '__builtin_nansq' { return __builtin_nansq(""); } ^
On Wed, May 31, 2023 at 03:04:03PM +0100, Jonathan Wakely via Gcc-patches wrote: > On Wed, 31 May 2023 at 13:23, Jonathan Wakely via Libstdc++ < > libstdc++@gcc.gnu.org> wrote: > > > Tested powerpc64le-linux. Pushed to trunk. > > > > -- >8 -- > > > > As suggested by Jakub in the PR, this just hardcodes the constants with > > a Q suffix, since the properties of __float128 are not going to change. > > > > We can only define it for non-strict modes because the suffix gives an > > error otherwise, even in system headers: > > > > limits:2085: error: unable to find numeric literal operator 'operator""Q' > > > > libstdc++-v3/ChangeLog: > > > > PR libstdc++/104772 > > * include/std/limits (numeric_limits<__float128>): Define. > > * testsuite/18_support/numeric_limits/128bit.cc: New test. > > > > I should have tested this with clang before pushing: > > /home/jwakely/gcc/latest/lib/gcc/x86_64-pc-linux-gnu/14.0.0/../../../../include/c++/14.0.0/limits:2125: > 16: error: use of undeclared identifier '__builtin_huge_valq' > { return __builtin_huge_valq(); } > ^ > /home/jwakely/gcc/latest/lib/gcc/x86_64-pc-linux-gnu/14.0.0/../../../../include/c++/14.0.0/limits:2129: > 16: error: use of undeclared identifier '__builtin_nanq' > { return __builtin_nanq(""); } > ^ > /home/jwakely/gcc/latest/lib/gcc/x86_64-pc-linux-gnu/14.0.0/../../../../include/c++/14.0.0/limits:2133: > 16: error: use of undeclared identifier '__builtin_nansq' > { return __builtin_nansq(""); } > ^ See my comments in bugzilla how to support this stuff even without being able to use Q suffixes. As for the builtins, no reason not to use __float128(__builtin_huge_val()) for the first case or __float128(__builtin_nan("")) for the second case. I'm afraid there is nothing that can be done about signalling NaN of neither __builtin_nansq nor __builtin_nansf128 is supported. Jakub
diff --git a/libstdc++-v3/include/std/limits b/libstdc++-v3/include/std/limits index 8bafd6fb972..5f341e63b93 100644 --- a/libstdc++-v3/include/std/limits +++ b/libstdc++-v3/include/std/limits @@ -2073,6 +2073,81 @@ __glibcxx_float_n(128) #endif +#if defined(_GLIBCXX_USE_FLOAT128) && !defined(__STRICT_ANSI__) + __extension__ + template<> + struct numeric_limits<__float128> + { + static _GLIBCXX_USE_CONSTEXPR bool is_specialized = true; + + static _GLIBCXX_CONSTEXPR __float128 + min() _GLIBCXX_USE_NOEXCEPT + { return __extension__ 3.36210314311209350626267781732175260e-4932Q; } + + static _GLIBCXX_CONSTEXPR __float128 + max() _GLIBCXX_USE_NOEXCEPT + { return __extension__ 1.18973149535723176508575932662800702e+4932Q; } + + static _GLIBCXX_CONSTEXPR __float128 + lowest() _GLIBCXX_USE_NOEXCEPT + { return -max(); } + + static _GLIBCXX_USE_CONSTEXPR int digits = 113; + static _GLIBCXX_USE_CONSTEXPR int digits10 = 33; + static _GLIBCXX_USE_CONSTEXPR int max_digits10 + = __glibcxx_max_digits10 (112); + static _GLIBCXX_USE_CONSTEXPR bool is_signed = true; + static _GLIBCXX_USE_CONSTEXPR bool is_integer = false; + static _GLIBCXX_USE_CONSTEXPR bool is_exact = false; + static _GLIBCXX_USE_CONSTEXPR int radix = __FLT_RADIX__; + + static _GLIBCXX_CONSTEXPR __float128 + epsilon() _GLIBCXX_USE_NOEXCEPT + { return __extension__ 1.92592994438723585305597794258492732e-34Q; } + + static _GLIBCXX_CONSTEXPR __float128 + round_error() _GLIBCXX_USE_NOEXCEPT { return __extension__ 0.5Q; } + + static _GLIBCXX_USE_CONSTEXPR int min_exponent = -16381; + static _GLIBCXX_USE_CONSTEXPR int min_exponent10 = -4931; + static _GLIBCXX_USE_CONSTEXPR int max_exponent = 16384; + static _GLIBCXX_USE_CONSTEXPR int max_exponent10 = 4932; + + static _GLIBCXX_USE_CONSTEXPR bool has_infinity = 1; + static _GLIBCXX_USE_CONSTEXPR bool has_quiet_NaN = 1; + static _GLIBCXX_USE_CONSTEXPR bool has_signaling_NaN = has_quiet_NaN; + static _GLIBCXX_USE_CONSTEXPR float_denorm_style has_denorm + = denorm_present; + static _GLIBCXX_USE_CONSTEXPR bool has_denorm_loss = false; + + static _GLIBCXX_CONSTEXPR __float128 + infinity() _GLIBCXX_USE_NOEXCEPT + { return __builtin_huge_valq(); } + + static _GLIBCXX_CONSTEXPR __float128 + quiet_NaN() _GLIBCXX_USE_NOEXCEPT + { return __builtin_nanq(""); } + + static _GLIBCXX_CONSTEXPR __float128 + signaling_NaN() _GLIBCXX_USE_NOEXCEPT + { return __builtin_nansq(""); } + + static _GLIBCXX_CONSTEXPR __float128 + denorm_min() _GLIBCXX_USE_NOEXCEPT + { return __extension__ 6.47517511943802511092443895822764655e-4966Q; } + + static _GLIBCXX_USE_CONSTEXPR bool is_iec559 + = has_infinity && has_quiet_NaN && has_denorm == denorm_present; + static _GLIBCXX_USE_CONSTEXPR bool is_bounded = true; + static _GLIBCXX_USE_CONSTEXPR bool is_modulo = false; + + static _GLIBCXX_USE_CONSTEXPR bool traps = false; + static _GLIBCXX_USE_CONSTEXPR bool tinyness_before = false; + static _GLIBCXX_USE_CONSTEXPR float_round_style round_style + = round_to_nearest; + }; +#endif // _GLIBCXX_USE_FLOAT128 && ! __STRICT_ANSI__ + _GLIBCXX_END_NAMESPACE_VERSION } // namespace diff --git a/libstdc++-v3/testsuite/18_support/numeric_limits/128bit.cc b/libstdc++-v3/testsuite/18_support/numeric_limits/128bit.cc new file mode 100644 index 00000000000..e8ea568df94 --- /dev/null +++ b/libstdc++-v3/testsuite/18_support/numeric_limits/128bit.cc @@ -0,0 +1,12 @@ +// { dg-do compile } + +#include <limits> + +#if __SIZEOF_FLOAT128__ && !defined __STRICT_ANSI__ +__extension__ template class std::numeric_limits<__float128>; +#endif + +#if __SIZEOF_INT128__ +__extension__ template class std::numeric_limits<__int128>; +__extension__ template class std::numeric_limits<unsigned __int128>; +#endif