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