]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /////////////////////////////////////////////////////////////// |
2 | // Copyright 2013 John Maddock. Distributed under the Boost | |
3 | // Software License, Version 1.0. (See accompanying file | |
92f5a8d4 | 4 | // LICENSE_1_0.txt or copy at https://www.boost.org/LICENSE_1_0.txt |
7c673cae FG |
5 | |
6 | #ifndef BOOST_MP_FLOAT128_HPP | |
7 | #define BOOST_MP_FLOAT128_HPP | |
8 | ||
1e59de90 TL |
9 | // https://gcc.gnu.org/onlinedocs/gcc/Floating-Types.html |
10 | #if !defined(__amd64__) && !defined(__amd64) && !defined(__x86_64__) && !defined(__x86_64) && !defined(_M_X64) && !defined(_M_AMD64) && \ | |
11 | !defined(i386) && !defined(__i386) && !defined(__i386__) && !defined(_M_IX86) && !defined(__X86__) && !defined(_X86_) && !defined(__I86__) && \ | |
12 | !defined(__ia64__) && !defined(_IA64) && !defined(__IA64__) && !defined(__ia64) && !defined(_M_IA64) && !defined(__itanium__) && \ | |
13 | !defined(__hppa__) && !defined(__HPPA__) && !defined(__hppa) && \ | |
14 | !defined(__powerpc) && !defined(_M_PPC) && !defined(_ARCH_PPC) && !defined(_ARCH_PPC64) && !defined(__PPCBROADWAY__) | |
15 | #error libquadmath only works on on i386, x86_64, IA-64, and hppa HP-UX, as well as on PowerPC GNU/Linux targets that enable the vector scalar (VSX) instruction set. | |
16 | #endif | |
17 | ||
18 | #include <tuple> | |
19 | #include <boost/multiprecision/detail/standalone_config.hpp> | |
7c673cae | 20 | #include <boost/multiprecision/number.hpp> |
1e59de90 TL |
21 | #include <boost/multiprecision/detail/hash.hpp> |
22 | #include <boost/multiprecision/detail/no_exceptions_support.hpp> | |
7c673cae FG |
23 | |
24 | #if defined(BOOST_INTEL) && !defined(BOOST_MP_USE_FLOAT128) && !defined(BOOST_MP_USE_QUAD) | |
92f5a8d4 TL |
25 | #if defined(BOOST_INTEL_CXX_VERSION) && (BOOST_INTEL_CXX_VERSION >= 1310) && defined(__GNUC__) |
26 | #if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6)) | |
27 | #define BOOST_MP_USE_FLOAT128 | |
28 | #endif | |
29 | #endif | |
30 | ||
31 | #ifndef BOOST_MP_USE_FLOAT128 | |
32 | #define BOOST_MP_USE_QUAD | |
33 | #endif | |
7c673cae FG |
34 | #endif |
35 | ||
36 | #if defined(__GNUC__) && !defined(BOOST_MP_USE_FLOAT128) && !defined(BOOST_MP_USE_QUAD) | |
92f5a8d4 | 37 | #define BOOST_MP_USE_FLOAT128 |
7c673cae FG |
38 | #endif |
39 | ||
40 | #if !defined(BOOST_MP_USE_FLOAT128) && !defined(BOOST_MP_USE_QUAD) | |
92f5a8d4 | 41 | #error "Sorry compiler is neither GCC, not Intel, don't know how to configure this header." |
7c673cae FG |
42 | #endif |
43 | #if defined(BOOST_MP_USE_FLOAT128) && defined(BOOST_MP_USE_QUAD) | |
92f5a8d4 | 44 | #error "Oh dear, both BOOST_MP_USE_FLOAT128 and BOOST_MP_USE_QUAD are defined, which one should I be using?" |
7c673cae FG |
45 | #endif |
46 | ||
47 | #if defined(BOOST_MP_USE_FLOAT128) | |
48 | ||
49 | extern "C" { | |
50 | #include <quadmath.h> | |
51 | } | |
52 | ||
1e59de90 | 53 | using float128_type = __float128; |
7c673cae FG |
54 | |
55 | #elif defined(BOOST_MP_USE_QUAD) | |
56 | ||
57 | #include <boost/multiprecision/detail/float_string_cvt.hpp> | |
58 | ||
1e59de90 | 59 | using float128_type = _Quad; |
7c673cae FG |
60 | |
61 | extern "C" { | |
62 | _Quad __ldexpq(_Quad, int); | |
63 | _Quad __frexpq(_Quad, int*); | |
64 | _Quad __fabsq(_Quad); | |
65 | _Quad __floorq(_Quad); | |
66 | _Quad __ceilq(_Quad); | |
67 | _Quad __sqrtq(_Quad); | |
68 | _Quad __truncq(_Quad); | |
69 | _Quad __expq(_Quad); | |
70 | _Quad __powq(_Quad, _Quad); | |
71 | _Quad __logq(_Quad); | |
72 | _Quad __log10q(_Quad); | |
73 | _Quad __sinq(_Quad); | |
74 | _Quad __cosq(_Quad); | |
75 | _Quad __tanq(_Quad); | |
76 | _Quad __asinq(_Quad); | |
77 | _Quad __acosq(_Quad); | |
78 | _Quad __atanq(_Quad); | |
79 | _Quad __sinhq(_Quad); | |
80 | _Quad __coshq(_Quad); | |
81 | _Quad __tanhq(_Quad); | |
82 | _Quad __fmodq(_Quad, _Quad); | |
83 | _Quad __atan2q(_Quad, _Quad); | |
84 | ||
85 | #define ldexpq __ldexpq | |
86 | #define frexpq __frexpq | |
87 | #define fabsq __fabsq | |
88 | #define floorq __floorq | |
89 | #define ceilq __ceilq | |
90 | #define sqrtq __sqrtq | |
91 | #define truncq __truncq | |
92 | #define expq __expq | |
93 | #define powq __powq | |
94 | #define logq __logq | |
95 | #define log10q __log10q | |
96 | #define sinq __sinq | |
97 | #define cosq __cosq | |
98 | #define tanq __tanq | |
99 | #define asinq __asinq | |
100 | #define acosq __acosq | |
101 | #define atanq __atanq | |
102 | #define sinhq __sinhq | |
103 | #define coshq __coshq | |
104 | #define tanhq __tanhq | |
105 | #define fmodq __fmodq | |
106 | #define atan2q __atan2q | |
107 | } | |
108 | ||
109 | inline _Quad isnanq(_Quad v) | |
110 | { | |
111 | return v != v; | |
112 | } | |
113 | inline _Quad isinfq(_Quad v) | |
114 | { | |
115 | return __fabsq(v) > 1.18973149535723176508575932662800702e4932Q; | |
116 | } | |
117 | ||
118 | #endif | |
119 | ||
92f5a8d4 TL |
120 | namespace boost { |
121 | namespace multiprecision { | |
f67539c2 TL |
122 | |
123 | #ifndef BOOST_MP_BITS_OF_FLOAT128_DEFINED | |
124 | ||
125 | namespace detail { | |
126 | ||
127 | template <> | |
128 | struct bits_of<float128_type> | |
129 | { | |
1e59de90 | 130 | static constexpr const unsigned value = 113; |
f67539c2 TL |
131 | }; |
132 | ||
133 | } | |
134 | ||
135 | #endif | |
136 | ||
92f5a8d4 | 137 | namespace backends { |
7c673cae FG |
138 | |
139 | struct float128_backend; | |
140 | ||
141 | } | |
142 | ||
143 | using backends::float128_backend; | |
144 | ||
92f5a8d4 | 145 | template <> |
1e59de90 | 146 | struct number_category<backends::float128_backend> : public std::integral_constant<int, number_kind_floating_point> |
92f5a8d4 | 147 | {}; |
b32b8144 | 148 | #if defined(BOOST_MP_USE_QUAD) |
92f5a8d4 | 149 | template <> |
1e59de90 | 150 | struct number_category<float128_type> : public std::integral_constant<int, number_kind_floating_point> |
92f5a8d4 | 151 | {}; |
b32b8144 | 152 | #endif |
7c673cae | 153 | |
1e59de90 | 154 | using float128 = number<float128_backend, et_off>; |
92f5a8d4 TL |
155 | |
156 | namespace quad_constants { | |
1e59de90 | 157 | constexpr float128_type quad_min = static_cast<float128_type>(1) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) / 1073741824; |
92f5a8d4 | 158 | |
1e59de90 | 159 | constexpr float128_type quad_denorm_min = static_cast<float128_type>(1) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) * static_cast<float128_type>(DBL_MIN) / 5.5751862996326557854e+42; |
92f5a8d4 TL |
160 | |
161 | constexpr double dbl_mult = 8.9884656743115795386e+307; // This has one bit set only. | |
1e59de90 TL |
162 | constexpr float128_type quad_max = (static_cast<float128_type>(1) - 9.62964972193617926527988971292463659e-35) // This now has all bits sets to 1 |
163 | * static_cast<float128_type>(dbl_mult) * static_cast<float128_type>(dbl_mult) * static_cast<float128_type>(dbl_mult) * static_cast<float128_type>(dbl_mult) * static_cast<float128_type>(dbl_mult) * static_cast<float128_type>(dbl_mult) * static_cast<float128_type>(dbl_mult) * static_cast<float128_type>(dbl_mult) * static_cast<float128_type>(dbl_mult) * static_cast<float128_type>(dbl_mult) * static_cast<float128_type>(dbl_mult) * static_cast<float128_type>(dbl_mult) * static_cast<float128_type>(dbl_mult) * static_cast<float128_type>(dbl_mult) * static_cast<float128_type>(dbl_mult) * static_cast<float128_type>(dbl_mult) * 65536; | |
92f5a8d4 TL |
164 | } // namespace quad_constants |
165 | ||
166 | #define BOOST_MP_QUAD_MIN boost::multiprecision::quad_constants::quad_min | |
167 | #define BOOST_MP_QUAD_DENORM_MIN boost::multiprecision::quad_constants::quad_denorm_min | |
168 | #define BOOST_MP_QUAD_MAX boost::multiprecision::quad_constants::quad_max | |
169 | ||
92f5a8d4 TL |
170 | |
171 | namespace backends { | |
7c673cae FG |
172 | |
173 | struct float128_backend | |
174 | { | |
1e59de90 TL |
175 | using signed_types = std::tuple<signed char, short, int, long, long long>; |
176 | using unsigned_types = std::tuple<unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>; | |
177 | using float_types = std::tuple<float, double, long double>; | |
178 | using exponent_type = int ; | |
7c673cae | 179 | |
92f5a8d4 | 180 | private: |
7c673cae | 181 | float128_type m_value; |
92f5a8d4 TL |
182 | |
183 | public: | |
1e59de90 TL |
184 | constexpr float128_backend() noexcept : m_value(0) {} |
185 | constexpr float128_backend(const float128_backend& o) noexcept : m_value(o.m_value) {} | |
186 | BOOST_MP_CXX14_CONSTEXPR float128_backend& operator=(const float128_backend& o) noexcept | |
7c673cae FG |
187 | { |
188 | m_value = o.m_value; | |
189 | return *this; | |
190 | } | |
191 | template <class T> | |
1e59de90 | 192 | constexpr float128_backend(const T& i, const typename std::enable_if<std::is_convertible<T, float128_type>::value>::type* = 0) noexcept(noexcept(std::declval<float128_type&>() = std::declval<const T&>())) |
92f5a8d4 | 193 | : m_value(i) {} |
7c673cae | 194 | template <class T> |
1e59de90 | 195 | BOOST_MP_CXX14_CONSTEXPR typename std::enable_if<boost::multiprecision::detail::is_arithmetic<T>::value || std::is_convertible<T, float128_type>::value, float128_backend&>::type operator=(const T& i) noexcept(noexcept(std::declval<float128_type&>() = std::declval<const T&>())) |
7c673cae FG |
196 | { |
197 | m_value = i; | |
198 | return *this; | |
199 | } | |
92f5a8d4 | 200 | BOOST_MP_CXX14_CONSTEXPR float128_backend(long double const& f) : m_value(f) |
7c673cae | 201 | { |
92f5a8d4 | 202 | if (::fabsl(f) > LDBL_MAX) |
1e59de90 | 203 | m_value = (f < 0) ? -static_cast<float128_type>(HUGE_VAL) : static_cast<float128_type>(HUGE_VAL); |
7c673cae | 204 | } |
92f5a8d4 | 205 | BOOST_MP_CXX14_CONSTEXPR float128_backend& operator=(long double const& f) |
7c673cae | 206 | { |
92f5a8d4 | 207 | if (f > LDBL_MAX) |
1e59de90 | 208 | m_value = static_cast<float128_type>(HUGE_VAL); |
92f5a8d4 | 209 | else if (-f > LDBL_MAX) |
1e59de90 | 210 | m_value = -static_cast<float128_type>(HUGE_VAL); |
7c673cae FG |
211 | else |
212 | m_value = f; | |
213 | return *this; | |
214 | } | |
92f5a8d4 | 215 | float128_backend& operator=(const char* s) |
7c673cae FG |
216 | { |
217 | #ifndef BOOST_MP_USE_QUAD | |
218 | char* p_end; | |
219 | m_value = strtoflt128(s, &p_end); | |
92f5a8d4 | 220 | if (p_end - s != (std::ptrdiff_t)std::strlen(s)) |
7c673cae | 221 | { |
1e59de90 | 222 | BOOST_MP_THROW_EXCEPTION(std::runtime_error("Unable to interpret input string as a floating point value")); |
7c673cae FG |
223 | } |
224 | #else | |
225 | boost::multiprecision::detail::convert_from_string(*this, s); | |
226 | #endif | |
227 | return *this; | |
228 | } | |
1e59de90 | 229 | BOOST_MP_CXX14_CONSTEXPR void swap(float128_backend& o) noexcept |
7c673cae | 230 | { |
92f5a8d4 TL |
231 | // We don't call std::swap here because it's no constexpr (yet): |
232 | float128_type t(o.value()); | |
233 | o.value() = m_value; | |
234 | m_value = t; | |
7c673cae | 235 | } |
92f5a8d4 | 236 | std::string str(std::streamsize digits, std::ios_base::fmtflags f) const |
7c673cae FG |
237 | { |
238 | #ifndef BOOST_MP_USE_QUAD | |
92f5a8d4 | 239 | char buf[128]; |
7c673cae | 240 | std::string format = "%"; |
92f5a8d4 | 241 | if (f & std::ios_base::showpos) |
7c673cae | 242 | format += "+"; |
92f5a8d4 | 243 | if (f & std::ios_base::showpoint) |
7c673cae FG |
244 | format += "#"; |
245 | format += ".*"; | |
1e59de90 | 246 | if ((digits == 0) && !(f & std::ios_base::fixed)) |
7c673cae FG |
247 | digits = 36; |
248 | format += "Q"; | |
92f5a8d4 TL |
249 | |
250 | if (f & std::ios_base::scientific) | |
7c673cae | 251 | format += "e"; |
92f5a8d4 | 252 | else if (f & std::ios_base::fixed) |
7c673cae FG |
253 | format += "f"; |
254 | else | |
255 | format += "g"; | |
256 | ||
92f5a8d4 TL |
257 | int v; |
258 | if ((f & std::ios_base::scientific) && (f & std::ios_base::fixed)) | |
259 | { | |
260 | v = quadmath_snprintf(buf, sizeof buf, "%Qa", m_value); | |
261 | } | |
262 | else | |
263 | { | |
264 | v = quadmath_snprintf(buf, sizeof buf, format.c_str(), digits, m_value); | |
265 | } | |
7c673cae | 266 | |
92f5a8d4 | 267 | if ((v < 0) || (v >= 127)) |
7c673cae | 268 | { |
92f5a8d4 | 269 | int v_max = v; |
1e59de90 | 270 | std::unique_ptr<char[]> buf2; |
92f5a8d4 TL |
271 | buf2.reset(new char[v + 3]); |
272 | v = quadmath_snprintf(&buf2[0], v_max + 3, format.c_str(), digits, m_value); | |
273 | if (v >= v_max + 3) | |
7c673cae | 274 | { |
1e59de90 | 275 | BOOST_MP_THROW_EXCEPTION(std::runtime_error("Formatting of float128_type failed.")); |
7c673cae FG |
276 | } |
277 | return &buf2[0]; | |
278 | } | |
279 | return buf; | |
280 | #else | |
1e59de90 | 281 | return boost::multiprecision::detail::convert_to_string(*this, digits ? digits : 36, f); |
7c673cae FG |
282 | #endif |
283 | } | |
1e59de90 | 284 | BOOST_MP_CXX14_CONSTEXPR void negate() noexcept |
7c673cae FG |
285 | { |
286 | m_value = -m_value; | |
287 | } | |
92f5a8d4 | 288 | BOOST_MP_CXX14_CONSTEXPR int compare(const float128_backend& o) const |
7c673cae FG |
289 | { |
290 | return m_value == o.m_value ? 0 : m_value < o.m_value ? -1 : 1; | |
291 | } | |
292 | template <class T> | |
92f5a8d4 | 293 | BOOST_MP_CXX14_CONSTEXPR int compare(const T& i) const |
7c673cae FG |
294 | { |
295 | return m_value == i ? 0 : m_value < i ? -1 : 1; | |
296 | } | |
92f5a8d4 | 297 | BOOST_MP_CXX14_CONSTEXPR float128_type& value() |
7c673cae FG |
298 | { |
299 | return m_value; | |
300 | } | |
92f5a8d4 | 301 | BOOST_MP_CXX14_CONSTEXPR const float128_type& value() const |
7c673cae FG |
302 | { |
303 | return m_value; | |
304 | } | |
305 | }; | |
306 | ||
92f5a8d4 | 307 | inline BOOST_MP_CXX14_CONSTEXPR void eval_add(float128_backend& result, const float128_backend& a) |
7c673cae FG |
308 | { |
309 | result.value() += a.value(); | |
310 | } | |
311 | template <class A> | |
92f5a8d4 | 312 | inline BOOST_MP_CXX14_CONSTEXPR void eval_add(float128_backend& result, const A& a) |
7c673cae FG |
313 | { |
314 | result.value() += a; | |
315 | } | |
92f5a8d4 | 316 | inline BOOST_MP_CXX14_CONSTEXPR void eval_subtract(float128_backend& result, const float128_backend& a) |
7c673cae FG |
317 | { |
318 | result.value() -= a.value(); | |
319 | } | |
320 | template <class A> | |
92f5a8d4 | 321 | inline BOOST_MP_CXX14_CONSTEXPR void eval_subtract(float128_backend& result, const A& a) |
7c673cae FG |
322 | { |
323 | result.value() -= a; | |
324 | } | |
92f5a8d4 | 325 | inline BOOST_MP_CXX14_CONSTEXPR void eval_multiply(float128_backend& result, const float128_backend& a) |
7c673cae FG |
326 | { |
327 | result.value() *= a.value(); | |
328 | } | |
329 | template <class A> | |
92f5a8d4 | 330 | inline BOOST_MP_CXX14_CONSTEXPR void eval_multiply(float128_backend& result, const A& a) |
7c673cae FG |
331 | { |
332 | result.value() *= a; | |
333 | } | |
92f5a8d4 | 334 | inline BOOST_MP_CXX14_CONSTEXPR void eval_divide(float128_backend& result, const float128_backend& a) |
7c673cae FG |
335 | { |
336 | result.value() /= a.value(); | |
337 | } | |
338 | template <class A> | |
92f5a8d4 | 339 | inline BOOST_MP_CXX14_CONSTEXPR void eval_divide(float128_backend& result, const A& a) |
7c673cae FG |
340 | { |
341 | result.value() /= a; | |
342 | } | |
343 | ||
92f5a8d4 | 344 | inline BOOST_MP_CXX14_CONSTEXPR void eval_add(float128_backend& result, const float128_backend& a, const float128_backend& b) |
7c673cae FG |
345 | { |
346 | result.value() = a.value() + b.value(); | |
347 | } | |
348 | template <class A> | |
92f5a8d4 | 349 | inline BOOST_MP_CXX14_CONSTEXPR void eval_add(float128_backend& result, const float128_backend& a, const A& b) |
7c673cae FG |
350 | { |
351 | result.value() = a.value() + b; | |
352 | } | |
92f5a8d4 | 353 | inline BOOST_MP_CXX14_CONSTEXPR void eval_subtract(float128_backend& result, const float128_backend& a, const float128_backend& b) |
7c673cae FG |
354 | { |
355 | result.value() = a.value() - b.value(); | |
356 | } | |
357 | template <class A> | |
92f5a8d4 | 358 | inline BOOST_MP_CXX14_CONSTEXPR void eval_subtract(float128_backend& result, const float128_backend& a, const A& b) |
7c673cae FG |
359 | { |
360 | result.value() = a.value() - b; | |
361 | } | |
362 | template <class A> | |
92f5a8d4 | 363 | inline BOOST_MP_CXX14_CONSTEXPR void eval_subtract(float128_backend& result, const A& a, const float128_backend& b) |
7c673cae FG |
364 | { |
365 | result.value() = a - b.value(); | |
366 | } | |
92f5a8d4 | 367 | inline BOOST_MP_CXX14_CONSTEXPR void eval_multiply(float128_backend& result, const float128_backend& a, const float128_backend& b) |
7c673cae FG |
368 | { |
369 | result.value() = a.value() * b.value(); | |
370 | } | |
371 | template <class A> | |
92f5a8d4 | 372 | inline BOOST_MP_CXX14_CONSTEXPR void eval_multiply(float128_backend& result, const float128_backend& a, const A& b) |
7c673cae FG |
373 | { |
374 | result.value() = a.value() * b; | |
375 | } | |
92f5a8d4 | 376 | inline BOOST_MP_CXX14_CONSTEXPR void eval_divide(float128_backend& result, const float128_backend& a, const float128_backend& b) |
7c673cae FG |
377 | { |
378 | result.value() = a.value() / b.value(); | |
379 | } | |
380 | ||
381 | template <class R> | |
92f5a8d4 | 382 | inline BOOST_MP_CXX14_CONSTEXPR void eval_convert_to(R* result, const float128_backend& val) |
7c673cae FG |
383 | { |
384 | *result = static_cast<R>(val.value()); | |
385 | } | |
386 | ||
387 | inline void eval_frexp(float128_backend& result, const float128_backend& arg, int* exp) | |
388 | { | |
389 | result.value() = frexpq(arg.value(), exp); | |
390 | } | |
391 | ||
392 | inline void eval_ldexp(float128_backend& result, const float128_backend& arg, int exp) | |
393 | { | |
394 | result.value() = ldexpq(arg.value(), exp); | |
395 | } | |
396 | ||
397 | inline void eval_floor(float128_backend& result, const float128_backend& arg) | |
398 | { | |
399 | result.value() = floorq(arg.value()); | |
400 | } | |
401 | inline void eval_ceil(float128_backend& result, const float128_backend& arg) | |
402 | { | |
403 | result.value() = ceilq(arg.value()); | |
404 | } | |
405 | inline void eval_sqrt(float128_backend& result, const float128_backend& arg) | |
406 | { | |
407 | result.value() = sqrtq(arg.value()); | |
408 | } | |
1e59de90 | 409 | |
20effc67 TL |
410 | inline void eval_rsqrt(float128_backend& result, const float128_backend& arg) |
411 | { | |
1e59de90 TL |
412 | #if (LDBL_MANT_DIG > 100) |
413 | // GCC can't mix and match __float128 and quad precision long double | |
414 | // error: __float128 and long double cannot be used in the same expression | |
415 | result.value() = 1 / sqrtq(arg.value()); | |
416 | #else | |
20effc67 TL |
417 | using std::sqrt; |
418 | if (arg.value() < std::numeric_limits<long double>::denorm_min() || arg.value() > (std::numeric_limits<long double>::max)()) { | |
419 | result.value() = 1/sqrtq(arg.value()); | |
420 | return; | |
421 | } | |
422 | float128_backend xk = 1/sqrt(static_cast<long double>(arg.value())); | |
423 | ||
424 | // Newton iteration for f(x) = arg.value() - 1/x^2. | |
425 | BOOST_IF_CONSTEXPR (sizeof(long double) == sizeof(double)) { | |
426 | // If the long double is the same as a double, then we need two Newton iterations: | |
427 | xk.value() = xk.value() + xk.value()*(1-arg.value()*xk.value()*xk.value())/2; | |
428 | result.value() = xk.value() + xk.value()*(1-arg.value()*xk.value()*xk.value())/2; | |
20effc67 | 429 | } |
1e59de90 TL |
430 | else |
431 | { | |
432 | // 80 bit long double only needs a single iteration to produce ~2ULPs. | |
433 | result.value() = xk.value() + xk.value() * (1 - arg.value() * xk.value() * xk.value()) / 2; | |
434 | } | |
435 | #endif | |
20effc67 | 436 | } |
92f5a8d4 TL |
437 | #ifndef BOOST_MP_NO_CONSTEXPR_DETECTION |
438 | inline BOOST_MP_CXX14_CONSTEXPR | |
439 | #else | |
440 | inline | |
441 | #endif | |
442 | int eval_fpclassify(const float128_backend& arg) | |
7c673cae | 443 | { |
92f5a8d4 TL |
444 | float128_type v = arg.value(); |
445 | #ifndef BOOST_MP_NO_CONSTEXPR_DETECTION | |
446 | if (BOOST_MP_IS_CONST_EVALUATED(v)) | |
447 | { | |
448 | if (v != v) | |
449 | return FP_NAN; | |
450 | if (v == 0) | |
451 | return FP_ZERO; | |
452 | float128_type t(v); | |
453 | if (t < 0) | |
454 | t = -t; | |
455 | if (t > BOOST_MP_QUAD_MAX) | |
456 | return FP_INFINITE; | |
457 | if (t < BOOST_MP_QUAD_MIN) | |
458 | return FP_SUBNORMAL; | |
459 | return FP_NORMAL; | |
460 | } | |
461 | else | |
462 | #endif | |
463 | { | |
464 | if (isnanq(v)) | |
465 | return FP_NAN; | |
466 | else if (isinfq(v)) | |
467 | return FP_INFINITE; | |
468 | else if (v == 0) | |
469 | return FP_ZERO; | |
470 | ||
471 | float128_backend t(arg); | |
472 | if (t.value() < 0) | |
473 | t.negate(); | |
474 | if (t.value() < BOOST_MP_QUAD_MIN) | |
475 | return FP_SUBNORMAL; | |
476 | return FP_NORMAL; | |
477 | } | |
7c673cae | 478 | } |
92f5a8d4 TL |
479 | #if defined(BOOST_GCC) && (__GNUC__ == 9) |
480 | // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91705 | |
481 | inline BOOST_MP_CXX14_CONSTEXPR void eval_increment(float128_backend& arg) | |
482 | { | |
483 | arg.value() = 1 + arg.value(); | |
484 | } | |
485 | inline BOOST_MP_CXX14_CONSTEXPR void eval_decrement(float128_backend& arg) | |
486 | { | |
487 | arg.value() = arg.value() - 1; | |
488 | } | |
489 | #else | |
490 | inline BOOST_MP_CXX14_CONSTEXPR void eval_increment(float128_backend& arg) | |
7c673cae FG |
491 | { |
492 | ++arg.value(); | |
493 | } | |
92f5a8d4 | 494 | inline BOOST_MP_CXX14_CONSTEXPR void eval_decrement(float128_backend& arg) |
7c673cae FG |
495 | { |
496 | --arg.value(); | |
497 | } | |
92f5a8d4 | 498 | #endif |
7c673cae FG |
499 | |
500 | /********************************************************************* | |
501 | * | |
502 | * abs/fabs: | |
503 | * | |
504 | *********************************************************************/ | |
505 | ||
92f5a8d4 TL |
506 | #ifndef BOOST_MP_NO_CONSTEXPR_DETECTION |
507 | inline BOOST_MP_CXX14_CONSTEXPR void eval_abs(float128_backend& result, const float128_backend& arg) | |
508 | #else | |
7c673cae | 509 | inline void eval_abs(float128_backend& result, const float128_backend& arg) |
92f5a8d4 | 510 | #endif |
7c673cae | 511 | { |
92f5a8d4 | 512 | #ifndef BOOST_MP_NO_CONSTEXPR_DETECTION |
1e59de90 | 513 | float128_type v(arg.value()); |
92f5a8d4 TL |
514 | if (BOOST_MP_IS_CONST_EVALUATED(v)) |
515 | { | |
516 | result.value() = v < 0 ? -v : v; | |
517 | } | |
518 | else | |
519 | #endif | |
520 | { | |
521 | result.value() = fabsq(arg.value()); | |
522 | } | |
7c673cae | 523 | } |
92f5a8d4 TL |
524 | #ifndef BOOST_MP_NO_CONSTEXPR_DETECTION |
525 | inline BOOST_MP_CXX14_CONSTEXPR void eval_fabs(float128_backend& result, const float128_backend& arg) | |
526 | #else | |
7c673cae | 527 | inline void eval_fabs(float128_backend& result, const float128_backend& arg) |
92f5a8d4 | 528 | #endif |
7c673cae | 529 | { |
92f5a8d4 | 530 | #ifndef BOOST_MP_NO_CONSTEXPR_DETECTION |
1e59de90 | 531 | float128_type v(arg.value()); |
92f5a8d4 TL |
532 | if (BOOST_MP_IS_CONST_EVALUATED(v)) |
533 | { | |
534 | result.value() = v < 0 ? -v : v; | |
535 | } | |
536 | else | |
537 | #endif | |
538 | { | |
539 | result.value() = fabsq(arg.value()); | |
540 | } | |
7c673cae FG |
541 | } |
542 | ||
543 | /********************************************************************* | |
544 | * | |
545 | * Floating point functions: | |
546 | * | |
547 | *********************************************************************/ | |
548 | ||
549 | inline void eval_trunc(float128_backend& result, const float128_backend& arg) | |
550 | { | |
7c673cae FG |
551 | result.value() = truncq(arg.value()); |
552 | } | |
553 | /* | |
554 | // | |
555 | // This doesn't actually work... rely on our own default version instead. | |
556 | // | |
557 | inline void eval_round(float128_backend& result, const float128_backend& arg) | |
558 | { | |
559 | if(isnanq(arg.value()) || isinf(arg.value())) | |
560 | { | |
561 | result = boost::math::policies::raise_rounding_error( | |
562 | "boost::multiprecision::trunc<%1%>(%1%)", 0, | |
563 | number<float128_backend, et_off>(arg), | |
564 | number<float128_backend, et_off>(arg), | |
565 | boost::math::policies::policy<>()).backend(); | |
566 | return; | |
567 | } | |
568 | result.value() = roundq(arg.value()); | |
569 | } | |
570 | */ | |
571 | ||
572 | inline void eval_exp(float128_backend& result, const float128_backend& arg) | |
573 | { | |
574 | result.value() = expq(arg.value()); | |
575 | } | |
576 | inline void eval_log(float128_backend& result, const float128_backend& arg) | |
577 | { | |
578 | result.value() = logq(arg.value()); | |
579 | } | |
580 | inline void eval_log10(float128_backend& result, const float128_backend& arg) | |
581 | { | |
582 | result.value() = log10q(arg.value()); | |
583 | } | |
584 | inline void eval_sin(float128_backend& result, const float128_backend& arg) | |
585 | { | |
586 | result.value() = sinq(arg.value()); | |
587 | } | |
588 | inline void eval_cos(float128_backend& result, const float128_backend& arg) | |
589 | { | |
590 | result.value() = cosq(arg.value()); | |
591 | } | |
592 | inline void eval_tan(float128_backend& result, const float128_backend& arg) | |
593 | { | |
594 | result.value() = tanq(arg.value()); | |
595 | } | |
596 | inline void eval_asin(float128_backend& result, const float128_backend& arg) | |
597 | { | |
598 | result.value() = asinq(arg.value()); | |
599 | } | |
600 | inline void eval_acos(float128_backend& result, const float128_backend& arg) | |
601 | { | |
602 | result.value() = acosq(arg.value()); | |
603 | } | |
604 | inline void eval_atan(float128_backend& result, const float128_backend& arg) | |
605 | { | |
606 | result.value() = atanq(arg.value()); | |
607 | } | |
608 | inline void eval_sinh(float128_backend& result, const float128_backend& arg) | |
609 | { | |
610 | result.value() = sinhq(arg.value()); | |
611 | } | |
612 | inline void eval_cosh(float128_backend& result, const float128_backend& arg) | |
613 | { | |
614 | result.value() = coshq(arg.value()); | |
615 | } | |
616 | inline void eval_tanh(float128_backend& result, const float128_backend& arg) | |
617 | { | |
618 | result.value() = tanhq(arg.value()); | |
619 | } | |
620 | inline void eval_fmod(float128_backend& result, const float128_backend& a, const float128_backend& b) | |
621 | { | |
622 | result.value() = fmodq(a.value(), b.value()); | |
623 | } | |
624 | inline void eval_pow(float128_backend& result, const float128_backend& a, const float128_backend& b) | |
625 | { | |
626 | result.value() = powq(a.value(), b.value()); | |
627 | } | |
628 | inline void eval_atan2(float128_backend& result, const float128_backend& a, const float128_backend& b) | |
629 | { | |
630 | result.value() = atan2q(a.value(), b.value()); | |
631 | } | |
92f5a8d4 | 632 | #ifndef BOOST_MP_USE_QUAD |
7c673cae FG |
633 | inline void eval_multiply_add(float128_backend& result, const float128_backend& a, const float128_backend& b, const float128_backend& c) |
634 | { | |
635 | result.value() = fmaq(a.value(), b.value(), c.value()); | |
636 | } | |
b32b8144 FG |
637 | inline int eval_signbit BOOST_PREVENT_MACRO_SUBSTITUTION(const float128_backend& arg) |
638 | { | |
639 | return ::signbitq(arg.value()); | |
640 | } | |
92f5a8d4 | 641 | #endif |
b32b8144 | 642 | |
7c673cae FG |
643 | inline std::size_t hash_value(const float128_backend& val) |
644 | { | |
1e59de90 | 645 | return boost::multiprecision::detail::hash_value(static_cast<double>(val.value())); |
7c673cae FG |
646 | } |
647 | ||
648 | } // namespace backends | |
649 | ||
92f5a8d4 TL |
650 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
651 | inline boost::multiprecision::number<float128_backend, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg) | |
652 | { | |
653 | return asinhq(arg.backend().value()); | |
654 | } | |
655 | template <boost::multiprecision::expression_template_option ExpressionTemplates> | |
656 | inline boost::multiprecision::number<float128_backend, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg) | |
657 | { | |
658 | return acoshq(arg.backend().value()); | |
659 | } | |
660 | template <boost::multiprecision::expression_template_option ExpressionTemplates> | |
661 | inline boost::multiprecision::number<float128_backend, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg) | |
662 | { | |
663 | return atanhq(arg.backend().value()); | |
664 | } | |
665 | template <boost::multiprecision::expression_template_option ExpressionTemplates> | |
666 | inline boost::multiprecision::number<float128_backend, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg) | |
667 | { | |
668 | return cbrtq(arg.backend().value()); | |
669 | } | |
670 | template <boost::multiprecision::expression_template_option ExpressionTemplates> | |
671 | inline boost::multiprecision::number<float128_backend, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg) | |
672 | { | |
673 | return erfq(arg.backend().value()); | |
674 | } | |
675 | template <boost::multiprecision::expression_template_option ExpressionTemplates> | |
676 | inline boost::multiprecision::number<float128_backend, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg) | |
677 | { | |
678 | return erfcq(arg.backend().value()); | |
679 | } | |
680 | template <boost::multiprecision::expression_template_option ExpressionTemplates> | |
681 | inline boost::multiprecision::number<float128_backend, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg) | |
682 | { | |
683 | return expm1q(arg.backend().value()); | |
684 | } | |
685 | template <boost::multiprecision::expression_template_option ExpressionTemplates> | |
686 | inline boost::multiprecision::number<float128_backend, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg) | |
687 | { | |
688 | return lgammaq(arg.backend().value()); | |
689 | } | |
690 | template <boost::multiprecision::expression_template_option ExpressionTemplates> | |
691 | inline boost::multiprecision::number<float128_backend, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg) | |
692 | { | |
f67539c2 TL |
693 | if(eval_signbit(arg.backend()) != 0) |
694 | { | |
695 | const bool result_is_neg = ((static_cast<unsigned long long>(floorq(-arg.backend().value())) % 2U) == 0U); | |
696 | ||
697 | const boost::multiprecision::number<float128_backend, ExpressionTemplates> result_of_tgammaq = fabsq(tgammaq(arg.backend().value())); | |
698 | ||
699 | return ((result_is_neg == false) ? result_of_tgammaq : -result_of_tgammaq); | |
700 | } | |
701 | else | |
702 | { | |
703 | return tgammaq(arg.backend().value()); | |
704 | } | |
92f5a8d4 TL |
705 | } |
706 | template <boost::multiprecision::expression_template_option ExpressionTemplates> | |
707 | inline boost::multiprecision::number<float128_backend, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg) | |
708 | { | |
709 | return log1pq(arg.backend().value()); | |
710 | } | |
20effc67 TL |
711 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
712 | inline boost::multiprecision::number<float128_backend, ExpressionTemplates> rsqrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg) | |
713 | { | |
714 | boost::multiprecision::number<float128_backend, ExpressionTemplates> res; | |
715 | eval_rsqrt(res.backend(), arg.backend()); | |
716 | return res; | |
717 | } | |
7c673cae | 718 | |
92f5a8d4 TL |
719 | #ifndef BOOST_MP_USE_QUAD |
720 | template <multiprecision::expression_template_option ExpressionTemplates> | |
721 | inline boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> copysign BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates>& a, const boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates>& b) | |
722 | { | |
723 | return ::copysignq(a.backend().value(), b.backend().value()); | |
724 | } | |
7c673cae | 725 | |
1e59de90 TL |
726 | namespace backends { |
727 | ||
92f5a8d4 TL |
728 | inline void eval_remainder(float128_backend& result, const float128_backend& a, const float128_backend& b) |
729 | { | |
730 | result.value() = remainderq(a.value(), b.value()); | |
731 | } | |
732 | inline void eval_remainder(float128_backend& result, const float128_backend& a, const float128_backend& b, int* pi) | |
733 | { | |
734 | result.value() = remquoq(a.value(), b.value(), pi); | |
735 | } | |
1e59de90 TL |
736 | } // namespace backends |
737 | ||
92f5a8d4 | 738 | #endif |
7c673cae FG |
739 | |
740 | } // namespace multiprecision | |
741 | ||
742 | namespace math { | |
743 | ||
92f5a8d4 TL |
744 | using boost::multiprecision::copysign; |
745 | using boost::multiprecision::signbit; | |
7c673cae FG |
746 | |
747 | } // namespace math | |
748 | ||
749 | } // namespace boost | |
750 | ||
1e59de90 | 751 | #ifndef BOOST_MP_STANDALONE |
92f5a8d4 TL |
752 | namespace boost { |
753 | namespace archive { | |
7c673cae FG |
754 | |
755 | class binary_oarchive; | |
756 | class binary_iarchive; | |
757 | ||
92f5a8d4 TL |
758 | } // namespace archive |
759 | ||
760 | namespace serialization { | |
761 | namespace float128_detail { | |
7c673cae FG |
762 | |
763 | template <class Archive> | |
1e59de90 | 764 | void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const std::integral_constant<bool, false>&, const std::integral_constant<bool, false>&) |
7c673cae FG |
765 | { |
766 | // saving | |
767 | // non-binary | |
768 | std::string s(val.str(0, std::ios_base::scientific)); | |
92f5a8d4 | 769 | ar& boost::make_nvp("value", s); |
7c673cae FG |
770 | } |
771 | template <class Archive> | |
1e59de90 | 772 | void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const std::integral_constant<bool, true>&, const std::integral_constant<bool, false>&) |
7c673cae FG |
773 | { |
774 | // loading | |
775 | // non-binary | |
776 | std::string s; | |
92f5a8d4 | 777 | ar& boost::make_nvp("value", s); |
7c673cae FG |
778 | val = s.c_str(); |
779 | } | |
780 | ||
781 | template <class Archive> | |
1e59de90 | 782 | void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const std::integral_constant<bool, false>&, const std::integral_constant<bool, true>&) |
7c673cae FG |
783 | { |
784 | // saving | |
785 | // binary | |
786 | ar.save_binary(&val, sizeof(val)); | |
787 | } | |
788 | template <class Archive> | |
1e59de90 | 789 | void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const std::integral_constant<bool, true>&, const std::integral_constant<bool, true>&) |
7c673cae FG |
790 | { |
791 | // loading | |
792 | // binary | |
793 | ar.load_binary(&val, sizeof(val)); | |
794 | } | |
795 | ||
92f5a8d4 | 796 | } // namespace float128_detail |
7c673cae FG |
797 | |
798 | template <class Archive> | |
799 | void serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, unsigned int /*version*/) | |
800 | { | |
1e59de90 TL |
801 | using load_tag = typename Archive::is_loading ; |
802 | using loading = std::integral_constant<bool, load_tag::value> ; | |
803 | using binary_tag = typename std::integral_constant<bool, std::is_same<Archive, boost::archive::binary_oarchive>::value || std::is_same<Archive, boost::archive::binary_iarchive>::value>; | |
7c673cae | 804 | |
1e59de90 | 805 | float128_detail::do_serialize(ar, val, loading(), binary_tag()); |
7c673cae FG |
806 | } |
807 | ||
92f5a8d4 | 808 | } // namespace serialization |
7c673cae FG |
809 | |
810 | } // namespace boost | |
1e59de90 | 811 | #endif // BOOST_MP_STANDALONE |
7c673cae | 812 | |
92f5a8d4 | 813 | namespace std { |
7c673cae FG |
814 | |
815 | template <boost::multiprecision::expression_template_option ExpressionTemplates> | |
816 | class numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> > | |
817 | { | |
1e59de90 | 818 | using number_type = boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates>; |
92f5a8d4 TL |
819 | |
820 | public: | |
1e59de90 TL |
821 | static constexpr bool is_specialized = true; |
822 | static BOOST_MP_CXX14_CONSTEXPR number_type(min)() noexcept { return BOOST_MP_QUAD_MIN; } | |
823 | static BOOST_MP_CXX14_CONSTEXPR number_type(max)() noexcept { return BOOST_MP_QUAD_MAX; } | |
824 | static BOOST_MP_CXX14_CONSTEXPR number_type lowest() noexcept { return -(max)(); } | |
825 | static constexpr int digits = 113; | |
826 | static constexpr int digits10 = 33; | |
827 | static constexpr int max_digits10 = 36; | |
828 | static constexpr bool is_signed = true; | |
829 | static constexpr bool is_integer = false; | |
830 | static constexpr bool is_exact = false; | |
831 | static constexpr int radix = 2; | |
92f5a8d4 TL |
832 | static BOOST_MP_CXX14_CONSTEXPR number_type epsilon() { return 1.92592994438723585305597794258492732e-34; /* this double value has only one bit set and so is exact */ } |
833 | static BOOST_MP_CXX14_CONSTEXPR number_type round_error() { return 0.5; } | |
1e59de90 TL |
834 | static constexpr int min_exponent = -16381; |
835 | static constexpr int min_exponent10 = min_exponent * 301L / 1000L; | |
836 | static constexpr int max_exponent = 16384; | |
837 | static constexpr int max_exponent10 = max_exponent * 301L / 1000L; | |
838 | static constexpr bool has_infinity = true; | |
839 | static constexpr bool has_quiet_NaN = true; | |
840 | static constexpr bool has_signaling_NaN = false; | |
841 | static constexpr float_denorm_style has_denorm = denorm_present; | |
842 | static constexpr bool has_denorm_loss = true; | |
92f5a8d4 | 843 | static BOOST_MP_CXX14_CONSTEXPR number_type infinity() { return HUGE_VAL; /* conversion from double infinity OK */ } |
1e59de90 | 844 | static BOOST_MP_CXX14_CONSTEXPR number_type quiet_NaN() { return number_type(NAN); } |
92f5a8d4 TL |
845 | static BOOST_MP_CXX14_CONSTEXPR number_type signaling_NaN() { return 0; } |
846 | static BOOST_MP_CXX14_CONSTEXPR number_type denorm_min() { return BOOST_MP_QUAD_DENORM_MIN; } | |
1e59de90 TL |
847 | static constexpr bool is_iec559 = true; |
848 | static constexpr bool is_bounded = true; | |
849 | static constexpr bool is_modulo = false; | |
850 | static constexpr bool traps = false; | |
851 | static constexpr bool tinyness_before = false; | |
852 | static constexpr float_round_style round_style = round_to_nearest; | |
7c673cae FG |
853 | }; |
854 | ||
855 | template <boost::multiprecision::expression_template_option ExpressionTemplates> | |
1e59de90 | 856 | constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_specialized; |
7c673cae | 857 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
1e59de90 | 858 | constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits; |
7c673cae | 859 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
1e59de90 | 860 | constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits10; |
7c673cae | 861 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
1e59de90 | 862 | constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_digits10; |
7c673cae FG |
863 | |
864 | template <boost::multiprecision::expression_template_option ExpressionTemplates> | |
1e59de90 | 865 | constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_signed; |
7c673cae | 866 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
1e59de90 | 867 | constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_integer; |
7c673cae | 868 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
1e59de90 | 869 | constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_exact; |
7c673cae | 870 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
1e59de90 | 871 | constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::radix; |
7c673cae | 872 | |
7c673cae | 873 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
1e59de90 | 874 | constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent; |
7c673cae | 875 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
1e59de90 | 876 | constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent; |
7c673cae | 877 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
1e59de90 | 878 | constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent10; |
7c673cae | 879 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
1e59de90 | 880 | constexpr int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent10; |
7c673cae FG |
881 | |
882 | template <boost::multiprecision::expression_template_option ExpressionTemplates> | |
1e59de90 | 883 | constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_infinity; |
7c673cae | 884 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
1e59de90 | 885 | constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_quiet_NaN; |
7c673cae | 886 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
1e59de90 | 887 | constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_signaling_NaN; |
7c673cae | 888 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
1e59de90 | 889 | constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_denorm_loss; |
7c673cae FG |
890 | |
891 | template <boost::multiprecision::expression_template_option ExpressionTemplates> | |
1e59de90 | 892 | constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_iec559; |
7c673cae | 893 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
1e59de90 | 894 | constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_bounded; |
7c673cae | 895 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
1e59de90 | 896 | constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_modulo; |
7c673cae | 897 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
1e59de90 | 898 | constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::traps; |
7c673cae | 899 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
1e59de90 | 900 | constexpr bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::tinyness_before; |
7c673cae FG |
901 | |
902 | template <boost::multiprecision::expression_template_option ExpressionTemplates> | |
1e59de90 | 903 | constexpr float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::round_style; |
7c673cae | 904 | template <boost::multiprecision::expression_template_option ExpressionTemplates> |
1e59de90 | 905 | constexpr float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_denorm; |
7c673cae FG |
906 | |
907 | } // namespace std | |
908 | ||
7c673cae | 909 | #endif |