Fix conflict between cstdfloat.hpp and multiprecision. (#474)

* Tentatively fix conflict between cstdfloat.hpp and multiprecision.

* Add missing struct to new code path.

* Reconfigure again for cstdfloat.hpp interop.

* Add missing #includes to float128.hpp.
Make constexpr __float128 arithmetic tests behave the same way, irrespective of whether numberic_limits is specialized for that type.

* Make tests conditional on BOOST_HAS_FLOAT128
This commit is contained in:
jzmaddock
2022-06-17 18:37:06 +01:00
committed by GitHub
parent 9f55ad5007
commit 7e677e83eb
5 changed files with 30 additions and 9 deletions
@@ -11,7 +11,14 @@
#include <boost/multiprecision/detail/standalone_config.hpp> #include <boost/multiprecision/detail/standalone_config.hpp>
#ifdef BOOST_HAS_FLOAT128 #ifndef BOOST_MP_STANDALONE
#include <boost/cstdfloat.hpp>
#if defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT)
# define BOOST_MP_HAVE_CSTDFLOAT
#endif
#endif
#if defined(BOOST_HAS_FLOAT128)
namespace boost namespace boost
{ {
@@ -27,10 +34,15 @@ extern "C" int isinfq(__float128) throw();
extern "C" int isnanq(__float128) throw(); extern "C" int isnanq(__float128) throw();
extern "C" __float128 strtoflt128(const char*, char**) throw(); extern "C" __float128 strtoflt128(const char*, char**) throw();
#ifdef BOOST_MP_HAVE_CSTDFLOAT
using std::ldexp;
using std::frexp;
using std::floor;
#else
inline __float128 ldexp(__float128 f, int i) throw() { return ldexpq(f, i); } inline __float128 ldexp(__float128 f, int i) throw() { return ldexpq(f, i); }
inline __float128 frexp(__float128 f, int* p) throw() { return frexpq(f, p); } inline __float128 frexp(__float128 f, int* p) throw() { return frexpq(f, p); }
inline __float128 floor(__float128 f) throw() { return floorq(f); } inline __float128 floor(__float128 f) throw() { return floorq(f); }
#endif
} }
namespace detail { namespace detail {
@@ -16,7 +16,10 @@
#endif #endif
#include <memory> #include <memory>
#include <climits>
#include <cfloat>
#include <tuple> #include <tuple>
#include <cstring>
#include <boost/multiprecision/detail/standalone_config.hpp> #include <boost/multiprecision/detail/standalone_config.hpp>
#include <boost/multiprecision/number.hpp> #include <boost/multiprecision/number.hpp>
#include <boost/multiprecision/detail/hash.hpp> #include <boost/multiprecision/detail/hash.hpp>
+9 -3
View File
@@ -9,11 +9,17 @@
// clang-format off // clang-format off
#ifdef BOOST_HAS_FLOAT128
#define OR_IS_FLOAT128 || std::is_same<__float128, U>::value
#else
#define OR_IS_FLOAT128
#endif
template <class T, class U> template <class T, class U>
BOOST_CXX14_CONSTEXPR T do_test_constexpr_add_subtract(T a, U b) BOOST_CXX14_CONSTEXPR T do_test_constexpr_add_subtract(T a, U b)
{ {
a = +b; a = +b;
if constexpr(std::numeric_limits<U>::is_signed && std::numeric_limits<T>::is_signed) if constexpr((std::numeric_limits<U>::is_signed OR_IS_FLOAT128) && std::numeric_limits<T>::is_signed)
b = -b; b = -b;
a += b; a += b;
a += a; a += a;
@@ -26,13 +32,13 @@ BOOST_CXX14_CONSTEXPR T do_test_constexpr_add_subtract(T a, U b)
a += bb--; a += bb--;
a = a + b; a = a + b;
a += a - b; a += a - b;
if constexpr(std::numeric_limits<U>::is_signed && std::numeric_limits<T>::is_signed) if constexpr((std::numeric_limits<U>::is_signed OR_IS_FLOAT128) && std::numeric_limits<T>::is_signed)
a -= b - -a; a -= b - -a;
a += b + a; a += b + a;
if constexpr(std::numeric_limits<T>::is_signed) if constexpr(std::numeric_limits<T>::is_signed)
{ {
a = -a; a = -a;
if constexpr(std::numeric_limits<U>::is_signed) if constexpr(std::numeric_limits<U>::is_signed OR_IS_FLOAT128)
a -= b; a -= b;
} }
return a; return a;
+3 -3
View File
@@ -16,13 +16,13 @@ int main()
constexpr float128 b = test_constexpr_add_subtract(a); constexpr float128 b = test_constexpr_add_subtract(a);
constexpr __float128 f128 = (__float128)b; constexpr __float128 f128 = (__float128)b;
static_assert(f128 == -134.0f); static_assert(f128 == -108.0f);
constexpr int i = (int)b; constexpr int i = (int)b;
static_assert(i == -134); static_assert(i == -108);
constexpr short s = (short)b; constexpr short s = (short)b;
static_assert(s == -134); static_assert(s == -108);
} }
{ {
constexpr float128 a(22); constexpr float128 a(22);
+1 -1
View File
@@ -167,7 +167,7 @@ std::ostream& operator<<(std::ostream& os, unsigned __int128 val)
} }
#endif #endif
#ifdef BOOST_HAS_FLOAT128 #if defined(BOOST_HAS_FLOAT128) && !defined(BOOST_MP_HAVE_CSTDFLOAT)
std::ostream& operator<<(std::ostream& os, __float128 f) std::ostream& operator<<(std::ostream& os, __float128 f)
{ {
return os << static_cast<long double>(f); return os << static_cast<long double>(f);