std::numeric_limits<__float128>::signaling_NaN + __float128-Type
Hello, please see https://godbolt.org/z/Ksshxvhaj 1) std::numeric_limits<__float128>::signaling_NaN always returns 0 but gcc-__builtin_nansq doesn't. I think __builtin_nansq is correct as it is also distinct from std::numeric_limits<__float128>::quiet_NaN (__builtin_nanq). 2) The types __float128, __extension__ __float128 (gcc) and _Quad (intel) are identical, but there are different definitions in boost/config/detail/suffix.hpp and boost/math/cstdfloat/cstdfloat_types.hpp. I think it would make sense to have just one definition or is there a reason why it was done that way? If yes, which one is it? You could always use __float128 directly and/or adjust boost/config/detail/suffix.hpp so that it also works with clang/intel. Which way would be better? I would like to help consolidate this but without having to deal with different typedef's or long #define's. thx Gero
Hello, please see https://godbolt.org/z/Ksshxvhaj
1) std::numeric_limits<__float128>::signaling_NaN always returns 0 but gcc-__builtin_nansq doesn't. I think __builtin_nansq is correct as it is also distinct from std::numeric_limits<__float128>::quiet_NaN (__builtin_nanq). Can you submit a PR please? We would probably need to check for the
On 07/02/2022 19:18, Gero Peterhoff via Boost wrote: presence of the intrinsic with __has_intrinsic as I don't *think* it's always been available?
2) The types __float128, __extension__ __float128 (gcc) and _Quad (intel) are identical, but there are different definitions in boost/config/detail/suffix.hpp and boost/math/cstdfloat/cstdfloat_types.hpp. I think it would make sense to have just one definition or is there a reason why it was done that way? If yes, which one is it? You could always use __float128 directly and/or adjust boost/config/detail/suffix.hpp so that it also works with clang/intel. Which way would be better?
There are two points here: __float128 and _Quad have similar functionality, but are different types with a different set of support functions and headers. You also need to remember that Boost.Math is now usable standalone (ie without the rest of Boost, including Boost.Config), so there will be some duplication of effort, but as it's a one line configuration, I really don't see that as a big issue? John. -- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus
Am 10.02.22 um 14:07 schrieb John Maddock via Boost:
On 07/02/2022 19:18, Gero Peterhoff via Boost wrote:
Hello, please see https://godbolt.org/z/Ksshxvhaj
1) std::numeric_limits<__float128>::signaling_NaN always returns 0 but gcc-__builtin_nansq doesn't. I think __builtin_nansq is correct as it is also distinct from std::numeric_limits<__float128>::quiet_NaN (__builtin_nanq). Can you submit a PR please? We would probably need to check for the presence of the intrinsic with __has_intrinsic as I don't *think* it's always been available?
Hi John, I can't think of anything besides the sledgehammer method (cast) either, assuming the value of gcc __builtin_nansq is universal.
namespace boost { namespace math { namespace cstdfloat { namespace detail { using float128_snan_array = std::integral_constant<std::array<uint64_t, 2>, std::array<uint64_t, 2>{0ULL, 9223160930622242816ULL}>; #if defined(__cpp_inline_variables) && defined(__cpp_lib_bit_cast) inline constexpr float_internal128_t float128_snan_v = std::bit_cast<float_internal128_t>(float128_snan_array::value); #else static const float_internal128_t float128_snan_v = reinterpret_cast<const float_internal128_t&>(float128_snan_array::value); #endif }}}} #if __has_builtin(__builtin_nansq) /* gcc/clang */ #define BOOST_CSTDFLOAT_FLOAT128_SNAN (__builtin_nansq("")) #elif __has_builtin(__nansq) /* intel */ #define BOOST_CSTDFLOAT_FLOAT128_SNAN (__nansq("")) #else #define BOOST_CSTDFLOAT_FLOAT128_SNAN (boost::math::cstdfloat::detail::float128_snan_v) #endif Hints - intels __nanq returns a negative value, this can also happen with __nansq if available - on big-endian machines, the values of the array may need to be swapped. Gero.
2) The types __float128, __extension__ __float128 (gcc) and _Quad (intel) are identical, but there are different definitions in boost/config/detail/suffix.hpp and boost/math/cstdfloat/cstdfloat_types.hpp. I think it would make sense to have just one definition or is there a reason why it was done that way? If yes, which one is it? You could always use __float128 directly and/or adjust boost/config/detail/suffix.hpp so that it also works with clang/intel. Which way would be better?
There are two points here: __float128 and _Quad have similar functionality, but are different types with a different set of support functions and headers. You also need to remember that Boost.Math is now usable standalone (ie without the rest of Boost, including Boost.Config), so there will be some duplication of effort, but as it's a one line configuration, I really don't see that as a big issue?
John.
On 2/11/22 01:18, Gero Peterhoff via Boost wrote:
Am 10.02.22 um 14:07 schrieb John Maddock via Boost:
On 07/02/2022 19:18, Gero Peterhoff via Boost wrote:
Hello, please see https://godbolt.org/z/Ksshxvhaj
1) std::numeric_limits<__float128>::signaling_NaN always returns 0 but gcc-__builtin_nansq doesn't. I think __builtin_nansq is correct as it is also distinct from std::numeric_limits<__float128>::quiet_NaN (__builtin_nanq). Can you submit a PR please? We would probably need to check for the presence of the intrinsic with __has_intrinsic as I don't *think* it's always been available?
Hi John, I can't think of anything besides the sledgehammer method (cast) either, assuming the value of gcc __builtin_nansq is universal.
namespace boost { namespace math { namespace cstdfloat { namespace detail { using float128_snan_array = std::integral_constant<std::array<uint64_t, 2>, std::array<uint64_t, 2>{0ULL, 9223160930622242816ULL}>;
#if defined(__cpp_inline_variables) && defined(__cpp_lib_bit_cast) inline constexpr float_internal128_t float128_snan_v = std::bit_cast<float_internal128_t>(float128_snan_array::value); #else static const float_internal128_t float128_snan_v = reinterpret_cast<const float_internal128_t&>(float128_snan_array::value); #endif }}}}
#if __has_builtin(__builtin_nansq) /* gcc/clang */
Older gcc versions don't have __has_builtin. But you could probably test which versions support the intrinsic on https://gcc.godbolt.org/.
#define BOOST_CSTDFLOAT_FLOAT128_SNAN (__builtin_nansq("")) #elif __has_builtin(__nansq) /* intel */ #define BOOST_CSTDFLOAT_FLOAT128_SNAN (__nansq("")) #else #define BOOST_CSTDFLOAT_FLOAT128_SNAN (boost::math::cstdfloat::detail::float128_snan_v) #endif
Hints - intels __nanq returns a negative value, this can also happen with __nansq if available - on big-endian machines, the values of the array may need to be swapped.
Gero.
2) The types __float128, __extension__ __float128 (gcc) and _Quad (intel) are identical, but there are different definitions in boost/config/detail/suffix.hpp and boost/math/cstdfloat/cstdfloat_types.hpp. I think it would make sense to have just one definition or is there a reason why it was done that way? If yes, which one is it? You could always use __float128 directly and/or adjust boost/config/detail/suffix.hpp so that it also works with clang/intel. Which way would be better?
There are two points here: __float128 and _Quad have similar functionality, but are different types with a different set of support functions and headers. You also need to remember that Boost.Math is now usable standalone (ie without the rest of Boost, including Boost.Config), so there will be some duplication of effort, but as it's a one line configuration, I really don't see that as a big issue?
John.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On 10/02/2022 22:18, Gero Peterhoff via Boost wrote:
Am 10.02.22 um 14:07 schrieb John Maddock via Boost:
On 07/02/2022 19:18, Gero Peterhoff via Boost wrote:
Hello, please see https://godbolt.org/z/Ksshxvhaj
1) std::numeric_limits<__float128>::signaling_NaN always returns 0 but gcc-__builtin_nansq doesn't. I think __builtin_nansq is correct as it is also distinct from std::numeric_limits<__float128>::quiet_NaN (__builtin_nanq). Can you submit a PR please? We would probably need to check for the presence of the intrinsic with __has_intrinsic as I don't *think* it's always been available? Hi John, I can't think of anything besides the sledgehammer method (cast) either, assuming the value of gcc __builtin_nansq is universal.
I'm not sure it's actually supported at all, I see: undefined reference to `nansq' whenever I try to use the builtin, the function nansq appears not to currently exist at all in libquadmath, and isn't declared in current quadmath.h. A quick google yields no hits as well. I wonder if this is still work in progress for gcc? Does anyone have a (non-theoretical) use case for signalling quad-precision NaN's? And or a working test case? Thanks, John. -- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus
Am 11.02.22 um 19:24 schrieb John Maddock via Boost:
On 10/02/2022 22:18, Gero Peterhoff via Boost wrote:
Am 10.02.22 um 14:07 schrieb John Maddock via Boost:
On 07/02/2022 19:18, Gero Peterhoff via Boost wrote:
Hello, please see https://godbolt.org/z/Ksshxvhaj
1) std::numeric_limits<__float128>::signaling_NaN always returns 0 but gcc-__builtin_nansq doesn't. I think __builtin_nansq is correct as it is also distinct from std::numeric_limits<__float128>::quiet_NaN (__builtin_nanq). Can you submit a PR please? We would probably need to check for the presence of the intrinsic with __has_intrinsic as I don't *think* it's always been available? Hi John, I can't think of anything besides the sledgehammer method (cast) either, assuming the value of gcc __builtin_nansq is universal.
I'm not sure it's actually supported at all, I see:
undefined reference to `nansq'
whenever I try to use the builtin, the function nansq appears not to currently exist at all in libquadmath, and isn't declared in current quadmath.h. A quick google yields no hits as well.
I wonder if this is still work in progress for gcc?
Does anyone have a (non-theoretical) use case for signalling quad-precision NaN's? And or a working test case?
Thanks, John.
Hi John, i hope the two functions boost::qnanf128/boost::snanf128 now return correct values/bit patterns. However, this implementation requires u/int128; if necessary, you can rewrite that to std::array<uint64_t, 2>. https://godbolt.org/z/W3bszoxW7 thx Gero
Am 11.02.22 um 19:24 schrieb John Maddock via Boost:
On 10/02/2022 22:18, Gero Peterhoff via Boost wrote:
Am 10.02.22 um 14:07 schrieb John Maddock via Boost:
On 07/02/2022 19:18, Gero Peterhoff via Boost wrote:
Hello, please see https://godbolt.org/z/Ksshxvhaj
1) std::numeric_limits<__float128>::signaling_NaN always returns 0 but gcc-__builtin_nansq doesn't. I think __builtin_nansq is correct as it is also distinct from std::numeric_limits<__float128>::quiet_NaN (__builtin_nanq). Can you submit a PR please? We would probably need to check for the presence of the intrinsic with __has_intrinsic as I don't *think* it's always been available? Hi John, I can't think of anything besides the sledgehammer method (cast) either, assuming the value of gcc __builtin_nansq is universal.
I'm not sure it's actually supported at all, I see:
undefined reference to `nansq'
whenever I try to use the builtin, the function nansq appears not to currently exist at all in libquadmath, and isn't declared in current quadmath.h. A quick google yields no hits as well.
I wonder if this is still work in progress for gcc?
Does anyone have a (non-theoretical) use case for signalling quad-precision NaN's? And or a working test case?
Thanks, John.
Hi John, regarding mail from just now; there's another bug in there (qnanf128 doesn't clear sign_bit); correct https://godbolt.org/z/9K1eKan6Y Gero
Am 11.02.22 um 19:24 schrieb John Maddock via Boost:
On 10/02/2022 22:18, Gero Peterhoff via Boost wrote:
Am 10.02.22 um 14:07 schrieb John Maddock via Boost:
On 07/02/2022 19:18, Gero Peterhoff via Boost wrote:
Hello, please see https://godbolt.org/z/Ksshxvhaj
1) std::numeric_limits<__float128>::signaling_NaN always returns 0 but gcc-__builtin_nansq doesn't. I think __builtin_nansq is correct as it is also distinct from std::numeric_limits<__float128>::quiet_NaN (__builtin_nanq). Can you submit a PR please? We would probably need to check for the presence of the intrinsic with __has_intrinsic as I don't *think* it's always been available? Hi John, I can't think of anything besides the sledgehammer method (cast) either, assuming the value of gcc __builtin_nansq is universal.
I'm not sure it's actually supported at all, I see:
undefined reference to `nansq'
whenever I try to use the builtin, the function nansq appears not to currently exist at all in libquadmath, and isn't declared in current quadmath.h. A quick google yields no hits as well.
I wonder if this is still work in progress for gcc?
Does anyone have a (non-theoretical) use case for signalling quad-precision NaN's? And or a working test case?
Thanks, John.
Crap, neither does snanf128, of course; hope that's it then :-) https://godbolt.org/z/v854oG8E5 Gero
Does anyone have a (non-theoretical) use case for signalling quad-precision NaN's? And or a working test case?
Thanks, John.
Crap, neither does snanf128, of course; hope that's it then :-) https://godbolt.org/z/v854oG8E5
That generates a NaN that has the same general appearance as a double-precision signalling NaN, but I'm unable to actually make it *signal*. Unless this is supported by GCC and libquadmath, it still looks to me that there are no signalling NaN's for __float128? To repeat myself: do you have a working test case where signalling NaN's actually do something useful? Otherwise it looks to me as though has_signalling_NaN really should be false? John. -- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus
Am 17.02.22 um 18:44 schrieb John Maddock via Boost:
Does anyone have a (non-theoretical) use case for signalling quad-precision NaN's? And or a working test case?
Thanks, John.
Crap, neither does snanf128, of course; hope that's it then :-) https://godbolt.org/z/v854oG8E5
That generates a NaN that has the same general appearance as a double-precision signalling NaN, but I'm unable to actually make it *signal*. Unless this is supported by GCC and libquadmath, it still looks to me that there are no signalling NaN's for __float128? To repeat myself: do you have a working test case where signalling NaN's actually do something useful? Otherwise it looks to me as though has_signalling_NaN really should be false?
John.
The difference between the values is (exponent: all bits set, sign bit cleared (libquadmath), https://en.wikipedia.org/wiki/NaN) qnan: the most significant fraction bit must be set and/or any fraction bit must be set snan: the most significant fraction bit must be clear and any fraction bit set. libquadmath always sets the second highest fraction bit. I don't have a real example either, but std::isnan should work. thx Gero
Hello John, i tinkered a bit so that std::isnan+std::fpclassify now also work with the value NANS (numeric_limits::signaling_NaN). For this i used the coming types and functions (stdlib.h). gcc supports this. That's why i don't want to speak directly of a patch, since this still has to be adapted for other compilers. It all boils down to that anyway, so please treat this as a pattern. The functions returns the same values as the gcc-builtins. However, i cannot say at the moment whether these are actually correct. But i have the feeling that not all of them are correct, since the (bit)schemes differ in part. adjusted (boost/math/cstdfloat) cstdfloat_types.hpp: add BOOST_CSTDFLOAT_FLOAT128_HUGE_VAL cstdfloat_limits.hpp: add forward-declarations for nanq/nansq in numeric_limits: change has_signaling_NaN to true, correct ? change infinity change quiet_NaN change signaling_NaN cstdfloat_cmath.hpp: add in detail:: a lot of functions change #define BOOST_CSTDFLOAT_FLOAT128_NAN add #define BOOST_CSTDFLOAT_FLOAT128_NANS change nanq add nansq add in std:: a lot of usings and functions regards Gero
On 21/02/2022 22:57, Gero Peterhoff via Boost wrote:
Hello John, i tinkered a bit so that std::isnan+std::fpclassify now also work with the value NANS (numeric_limits::signaling_NaN). For this i used the coming types and functions (stdlib.h). gcc supports this. That's why i don't want to speak directly of a patch, since this still has to be adapted for other compilers. It all boils down to that anyway, so please treat this as a pattern. The functions returns the same values as the gcc-builtins. However, i cannot say at the moment whether these are actually correct. But i have the feeling that not all of them are correct, since the (bit)schemes differ in part.
Apologies for the delay, I meant to reply to your previous message: here's the basic issue, yes you can create a __float128 which has the bit pattern a signalling NaN would have if supported, but based on my local tests on Mingw it's not actually supported by GCC or clang - which is to say they don't *raise a signal when used*. Unless you have a use case, and/or can show that __float128 is capable of raising a floating point exception when loaded into memory (and remember that we're talking about a type that is really a software emulation under the hood), then I just don't see signally NaN's as being supported for this type? Thanks, John.
adjusted (boost/math/cstdfloat)
cstdfloat_types.hpp: add BOOST_CSTDFLOAT_FLOAT128_HUGE_VAL
cstdfloat_limits.hpp: add forward-declarations for nanq/nansq in numeric_limits: change has_signaling_NaN to true, correct ? change infinity change quiet_NaN change signaling_NaN
cstdfloat_cmath.hpp: add in detail:: a lot of functions change #define BOOST_CSTDFLOAT_FLOAT128_NAN add #define BOOST_CSTDFLOAT_FLOAT128_NANS change nanq add nansq add in std:: a lot of usings and functions
regards Gero
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
-- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus
Apologies for the delay, I meant to reply to your previous message: here's the basic issue, yes you can create a __float128 which has the bit pattern a signalling NaN would have if supported, but based on my local tests on Mingw it's not actually supported by GCC or clang - which is to say they don't *raise a signal when used*.
Unless you have a use case, and/or can show that __float128 is capable of raising a floating point exception when loaded into memory (and remember that we're talking about a type that is really a software emulation under the hood), then I just don't see signally NaN's as being supported for this type?
Thanks, John.
Hi John, it is already clear to me that float128/libquadmath is only a sw-emulation, where not all features are supported at the moment. But with http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1467r5.html that will change (and then we won't have to bother with these problems any longer). Nevertheless, it makes sense to prepare the boost-libs now; be it just numeric_limits<float128>::signaling_NaN() to make isnan/fpclassify work. Unfortunately, I've only now found out that the gcc-builtins are not consistent and libquadmath::nanq doesn't work correctly. Reported the bugs and am waiting for an answer. regards Gero
On 25/02/2022 21:51, Gero Peterhoff via Boost wrote:
Apologies for the delay, I meant to reply to your previous message: here's the basic issue, yes you can create a __float128 which has the bit pattern a signalling NaN would have if supported, but based on my local tests on Mingw it's not actually supported by GCC or clang - which is to say they don't *raise a signal when used*.
Unless you have a use case, and/or can show that __float128 is capable of raising a floating point exception when loaded into memory (and remember that we're talking about a type that is really a software emulation under the hood), then I just don't see signally NaN's as being supported for this type?
Thanks, John. Hi John, it is already clear to me that float128/libquadmath is only a sw-emulation, where not all features are supported at the moment. But with http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1467r5.html that will change (and then we won't have to bother with these problems any longer). Nevertheless, it makes sense to prepare the boost-libs now; be it just numeric_limits<float128>::signaling_NaN() to make isnan/fpclassify work. Unfortunately, I've only now found out that the gcc-builtins are not consistent and libquadmath::nanq doesn't work correctly. Reported the bugs and am waiting for an answer.
To quote from the paper: "It is currently implementation-defined whether or not the floating-point types support infinity and NaN. That is not changing. That feature will still be implementation-defined, even for extended floating-point types." There is still no requirement to support NaN at all, much less signally NaN's which are traditionally dependent upon the underlying hardware. -- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus
participants (3)
-
Andrey Semashev
-
Gero Peterhoff
-
John Maddock