bug - boost::math::ccmath::copysign not work
Hi, I just see that boost::math::ccmath::copysign doesn't work. https://godbolt.org/z/9af1ME9fT cu Gero
On Aug 17, 2022, at 4:11 PM, Gero Peterhoff via Boost
wrote: Hi, I just see that boost::math::ccmath::copysign doesn't work. https://godbolt.org/z/9af1ME9fT
cu Gero
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Gero, The typical implementation of copysign and signbit involve type-punning which is not allowed in constexpr contexts. An example can be found here: https://android.googlesource.com/platform/bionic.git/+/brillo-m7-dev/libm/si.... Due to this limitation we do not provide support for signed zero or analyzing the sign of NAN. Matt
bit_cast is constexpr.
On Thu, 18 Aug 2022, 03:25 Proton via Boost,
On Aug 17, 2022, at 4:11 PM, Gero Peterhoff via Boost < boost@lists.boost.org> wrote:
Hi, I just see that boost::math::ccmath::copysign doesn't work. https://godbolt.org/z/9af1ME9fT
cu Gero
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Gero,
The typical implementation of copysign and signbit involve type-punning which is not allowed in constexpr contexts. An example can be found here: https://android.googlesource.com/platform/bionic.git/+/brillo-m7-dev/libm/si.... Due to this limitation we do not provide support for signed zero or analyzing the sign of NAN.
Matt
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
On 18/08/2022 07:23, Mathias Gaunard via Boost wrote:
bit_cast is constexpr.
Good catch! Matt and I discussed this ages ago and decided it was basically impossible, it's a shame that fix is C++20 but it's certainly better than nothing. Matt, here's a thought: if we can detect NaN's (and obviously zeros), can/should we static_assert in those cases that this is known not to work? Best, John.
On 8/18/22 13:13, John Maddock via Boost wrote:
On 18/08/2022 07:23, Mathias Gaunard via Boost wrote:
bit_cast is constexpr.
Good catch!
Matt and I discussed this ages ago and decided it was basically impossible, it's a shame that fix is C++20 but it's certainly better than nothing.
__builtin_bit_cast is available regardless of the C++ level. Though you're still limited to compilers that support it.
On Aug 18, 2022, at 5:26 AM, Andrey Semashev via Boost
wrote: On 8/18/22 13:13, John Maddock via Boost wrote:
On 18/08/2022 07:23, Mathias Gaunard via Boost wrote:
bit_cast is constexpr.
Good catch!
Matt and I discussed this ages ago and decided it was basically impossible, it's a shame that fix is C++20 but it's certainly better than nothing.
__builtin_bit_cast is available regardless of the C++ level. Though you're still limited to compilers that support it.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Using __builtin_bit_cast should be fine for conditional C++17 support since we already rely on __builtin_is_constant_evaluated. I’ll play with it this weekend and see where it get us. Worst case is we static_assert unsupported cases like John suggested. Matt
Am 19.08.22 um 03:53 schrieb Proton via Boost:
Using __builtin_bit_cast should be fine for conditional C++17 support since we already rely on __builtin_is_constant_evaluated. I’ll play with it this weekend and see where it get us. Worst case is we static_assert unsupported cases like John suggested.
Hi Matt, I see that you have started work on ccmath::signbit/copysign/etc. I also. Our basic problem is that std::bit_cast is only available with C++20. You are already trying to provide this for C++17 (BOOST_MATH_BIT_CAST). My questions: - can you *guarantee* that BOOST_MATH_BIT_CAST works on/with all platforms/compilers ? - if not: does it make sense to upgrade ccmath to C++20 so that std::bit_cast is available ? Otherwise I can only oracle and provide code to the best of my knowledge - without guarantee that it works on/with all platforms/compilers :-( regards Gero
On Aug 21, 2022, at 1:26 PM, Gero Peterhoff via Boost
wrote: Am 19.08.22 um 03:53 schrieb Proton via Boost:
Using __builtin_bit_cast should be fine for conditional C++17 support since we already rely on __builtin_is_constant_evaluated. I’ll play with it this weekend and see where it get us. Worst case is we static_assert unsupported cases like John suggested.
Hi Matt, I see that you have started work on ccmath::signbit/copysign/etc. I also. Our basic problem is that std::bit_cast is only available with C++20. You are already trying to provide this for C++17 (BOOST_MATH_BIT_CAST). My questions: - can you *guarantee* that BOOST_MATH_BIT_CAST works on/with all platforms/compilers ? - if not: does it make sense to upgrade ccmath to C++20 so that std::bit_cast is available ?
Otherwise I can only oracle and provide code to the best of my knowledge - without guarantee that it works on/with all platforms/compilers :-(
regards Gero
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Gero, I can make no such guarantees. I do not think it makes sense to upgrade to C++20 because BOOST_MATH_BIT_CAST macro enables C++17 support. If you look at the comments even with a move to C++20 Clang does not yet support constexpr std::bit_cast/__builtin_bit_cast with bit-fields. I have provided layouts for 64, 80, and 128 bit long doubles so most platforms should be covered if the toolchain supports it. Matt
Am 21.08.22 um 23:25 schrieb Proton:
On Aug 21, 2022, at 1:26 PM, Gero Peterhoff via Boost
wrote: Am 19.08.22 um 03:53 schrieb Proton via Boost:
Using __builtin_bit_cast should be fine for conditional C++17 support since we already rely on __builtin_is_constant_evaluated. I’ll play with it this weekend and see where it get us. Worst case is we static_assert unsupported cases like John suggested.
Hi Matt, I see that you have started work on ccmath::signbit/copysign/etc. I also. Our basic problem is that std::bit_cast is only available with C++20. You are already trying to provide this for C++17 (BOOST_MATH_BIT_CAST). My questions: - can you *guarantee* that BOOST_MATH_BIT_CAST works on/with all platforms/compilers ? - if not: does it make sense to upgrade ccmath to C++20 so that std::bit_cast is available ?
Otherwise I can only oracle and provide code to the best of my knowledge - without guarantee that it works on/with all platforms/compilers :-(
regards Gero
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
Gero,
I can make no such guarantees. I do not think it makes sense to upgrade to C++20 because BOOST_MATH_BIT_CAST macro enables C++17 support. If you look at the comments even with a move to C++20 Clang does not yet support constexpr std::bit_cast/__builtin_bit_cast with bit-fields. I have provided layouts for 64, 80, and 128 bit long doubles so most platforms should be covered if the toolchain supports it.
Matt
Hi Matt, I haven't tried whether clang's bit_cast supports bit fields. There is a problem with your simple implementation: Memory size for long double/float80 can be 10/12/16 bytes depending on platform or compiler option. You didn't take that into account, so bit_cast then fails. That's why I'm working on extended structures for the bitrepresentation for float-types, so that unusual or machine-specific types can also be mapped. These then also include manipulating the individual components and/or checking for special values. For the concrete implementations it would be advantageous to have a stable bit_cast; otherwise I can only use explicit bitpatterns and hope they are (ieee) compatible. This approach has other advantages. These extended structures always deliver correct results, even if the compiler option fast-math/finite-math or something similar is set. This can be used to implement various requirements, e.g. isnan/isinf: - isnan/isinf -> default - isnan_stable/isinf_stable -> correct results also with fast/finite-math etc This can be very useful when implementing math functions. Best, Gero
Hi Matt, I haven't tried whether clang's bit_cast supports bit fields. There is a problem with your simple implementation: Memory size for long double/float80 can be 10/12/16 bytes depending on platform or compiler option. You didn't take that into account, so bit_cast then fails.
That's why I'm working on extended structures for the bitrepresentation for float-types, so that unusual or machine-specific types can also be mapped. These then also include manipulating the individual components and/or checking for special values. For the concrete implementations it would be advantageous to have a stable bit_cast; otherwise I can only use explicit bitpatterns and hope they are (ieee) compatible.
This approach has other advantages. These extended structures always deliver correct results, even if the compiler option fast-math/finite-math or something similar is set. This can be used to implement various requirements, e.g. isnan/isinf: - isnan/isinf -> default - isnan_stable/isinf_stable -> correct results also with fast/finite-math etc
This can be very useful when implementing math functions.
Best, Gero
Gero, What platform does this fail on? I have provided multiple macro enabled definitions for the bit patterns of long doubles on major architectures. Have you run into issues with the implementations of isnan or isinf? We provide a version of fpclassify (https://www.boost.org/doc/libs/1_80_0/boost/math/special_functions/fpclassif...) that yields stable results regardless of the compiler flag like you are looking for. Matt
Am 22.08.22 um 02:11 schrieb Proton:
Hi Matt, I haven't tried whether clang's bit_cast supports bit fields. There is a problem with your simple implementation: Memory size for long double/float80 can be 10/12/16 bytes depending on platform or compiler option. You didn't take that into account, so bit_cast then fails.
That's why I'm working on extended structures for the bitrepresentation for float-types, so that unusual or machine-specific types can also be mapped. These then also include manipulating the individual components and/or checking for special values. For the concrete implementations it would be advantageous to have a stable bit_cast; otherwise I can only use explicit bitpatterns and hope they are (ieee) compatible.
This approach has other advantages. These extended structures always deliver correct results, even if the compiler option fast-math/finite-math or something similar is set. This can be used to implement various requirements, e.g. isnan/isinf: - isnan/isinf -> default - isnan_stable/isinf_stable -> correct results also with fast/finite-math etc
This can be very useful when implementing math functions.
Best, Gero
Gero,
What platform does this fail on? I have provided multiple macro enabled definitions for the bit patterns of long doubles on major architectures.
e.g. on x86 gcc (https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gcc/x86-Options.html#x86-Options): x86_64 sizeof(long double) == 16 x86_32 sizeof(long double) == 12 This can also be changed with compiler flags, eg with gcc -m96bit-long-double -m128bit-long-double and/or -mlong-double-64 -mlong-double-80 -mlong-double-128
Have you run into issues with the implementations of isnan or isinf? We provide a version of fpclassify (https://www.boost.org/doc/libs/1_80_0/boost/math/special_functions/fpclassif... https://www.boost.org/doc/libs/1_80_0/boost/math/special_functions/fpclassif...) that yields stable results regardless of the compiler flag like you are looking for.
But fpclassify is an if-else-cascade and not a direct and therefore fast test.
Matt
Gero
e.g. on x86 gcc (https://gcc.gnu.org/onlinedocs/gcc-12.2.0/gcc/x86-Options.html#x86-Options): x86_64 sizeof(long double) == 16 x86_32 sizeof(long double) == 12 This can also be changed with compiler flags, eg with gcc -m96bit-long-double -m128bit-long-double and/or -mlong-double-64 -mlong-double-80 -mlong-double-128
None of those fail on the PR branch. The appropriate representation of long double is macro enabled based on LDBL_MANT_DIG and LDBL_MAX_EXP. Matt
participants (5)
-
Andrey Semashev
-
Gero Peterhoff
-
John Maddock
-
Mathias Gaunard
-
Proton