1 ///////////////////////////////////////////////////////////////
2 //  Copyright 2013 John Maddock. Distributed under the Boost
3 //  Software License, Version 1.0. (See accompanying file
4 //  LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
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)
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
24 #endif
25 
26 #if defined(__GNUC__) && !defined(BOOST_MP_USE_FLOAT128) && !defined(BOOST_MP_USE_QUAD)
27 #  define BOOST_MP_USE_FLOAT128
28 #endif
29 
30 #if !defined(BOOST_MP_USE_FLOAT128) && !defined(BOOST_MP_USE_QUAD)
31 #  error "Sorry compiler is neither GCC, not Intel, don't know how to configure this header."
32 #endif
33 #if defined(BOOST_MP_USE_FLOAT128) && defined(BOOST_MP_USE_QUAD)
34 #  error "Oh dear, both BOOST_MP_USE_FLOAT128 and BOOST_MP_USE_QUAD are defined, which one should I be using?"
35 #endif
36 
37 #if defined(BOOST_MP_USE_FLOAT128)
38 
39 extern "C" {
40 #include <quadmath.h>
41 }
42 
43 typedef __float128 float128_type;
44 
45 #elif defined(BOOST_MP_USE_QUAD)
46 
47 #include <boost/multiprecision/detail/float_string_cvt.hpp>
48 
49 typedef _Quad float128_type;
50 
51 extern "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 
isnanq(_Quad v)99 inline _Quad isnanq(_Quad v)
100 {
101    return v != v;
102 }
isinfq(_Quad v)103 inline _Quad isinfq(_Quad v)
104 {
105    return __fabsq(v) > 1.18973149535723176508575932662800702e4932Q;
106 }
107 
108 #endif
109 
110 namespace boost{
111 namespace multiprecision{
112 namespace backends{
113 
114 struct float128_backend;
115 
116 }
117 
118 using backends::float128_backend;
119 
120 template<>
121 struct number_category<backends::float128_backend> : public mpl::int_<number_kind_floating_point> {};
122 template<>
123 struct number_category<float128_type> : public mpl::int_<number_kind_floating_point> {};
124 
125 typedef number<float128_backend, et_off> float128;
126 
127 namespace backends{
128 
129 struct float128_backend
130 {
131    typedef mpl::list<signed char, short, int, long, boost::long_long_type>   signed_types;
132    typedef mpl::list<unsigned char, unsigned short,
133       unsigned int, unsigned long, boost::ulong_long_type>           unsigned_types;
134    typedef mpl::list<float, double, long double>                 float_types;
135    typedef int                                                   exponent_type;
136 
137 private:
138    float128_type m_value;
139 public:
float128_backendboost::multiprecision::backends::float128_backend140    BOOST_CONSTEXPR float128_backend() BOOST_NOEXCEPT : m_value(0) {}
float128_backendboost::multiprecision::backends::float128_backend141    BOOST_CONSTEXPR float128_backend(const float128_backend& o) BOOST_NOEXCEPT : m_value(o.m_value) {}
operator =boost::multiprecision::backends::float128_backend142    float128_backend& operator = (const float128_backend& o) BOOST_NOEXCEPT
143    {
144       m_value = o.m_value;
145       return *this;
146    }
147    template <class T>
float128_backendboost::multiprecision::backends::float128_backend148    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&>()))
149       : m_value(i) {}
150    template <class T>
operator =boost::multiprecision::backends::float128_backend151    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&>()))
152    {
153       m_value = i;
154       return *this;
155    }
float128_backendboost::multiprecision::backends::float128_backend156    float128_backend(long double const& f)
157    {
158       if(boost::math::isinf(f))
159          m_value = (f < 0) ? -1.0Q / 0.0Q : 1.0Q / 0.0Q;
160       else
161          m_value = f;
162    }
operator =boost::multiprecision::backends::float128_backend163    float128_backend& operator=(long double const& f)
164    {
165       if(boost::math::isinf(f))
166          m_value = (f < 0) ? -1.0Q / 0.0Q : 1.0Q / 0.0Q;
167       else
168          m_value = f;
169       return *this;
170    }
operator =boost::multiprecision::backends::float128_backend171    float128_backend& operator = (const char* s)
172    {
173 #ifndef BOOST_MP_USE_QUAD
174       char* p_end;
175       m_value = strtoflt128(s, &p_end);
176       if(p_end - s != (std::ptrdiff_t)std::strlen(s))
177       {
178          BOOST_THROW_EXCEPTION(std::runtime_error("Unable to interpret input string as a floating point value"));
179       }
180 #else
181       boost::multiprecision::detail::convert_from_string(*this, s);
182 #endif
183       return *this;
184    }
swapboost::multiprecision::backends::float128_backend185    void swap(float128_backend& o) BOOST_NOEXCEPT
186    {
187       std::swap(m_value, o.value());
188    }
strboost::multiprecision::backends::float128_backend189    std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
190    {
191 #ifndef BOOST_MP_USE_QUAD
192       char buf[100];
193       boost::scoped_array<char> buf2;
194       std::string format = "%";
195       if(f & std::ios_base::showpos)
196          format += "+";
197       if(f & std::ios_base::showpoint)
198          format += "#";
199       format += ".*";
200       if(digits == 0)
201          digits = 36;
202       format += "Q";
203       if(f & std::ios_base::scientific)
204          format += "e";
205       else if(f & std::ios_base::fixed)
206          format += "f";
207       else
208          format += "g";
209 
210       int v = quadmath_snprintf (buf, 100, format.c_str(), digits, m_value);
211 
212       if((v < 0) || (v >= 99))
213       {
214          int v_max = v;
215          buf2.reset(new char[v+3]);
216          v = quadmath_snprintf (&buf2[0], v_max + 3, format.c_str(), digits, m_value);
217          if(v >= v_max + 3)
218          {
219             BOOST_THROW_EXCEPTION(std::runtime_error("Formatting of float128_type failed."));
220          }
221          return &buf2[0];
222       }
223       return buf;
224 #else
225       return boost::multiprecision::detail::convert_to_string(*this, digits ? digits : 37, f);
226 #endif
227    }
negateboost::multiprecision::backends::float128_backend228    void negate() BOOST_NOEXCEPT
229    {
230       m_value = -m_value;
231    }
compareboost::multiprecision::backends::float128_backend232    int compare(const float128_backend& o)const
233    {
234       return m_value == o.m_value ? 0 : m_value < o.m_value ? -1 : 1;
235    }
236    template <class T>
compareboost::multiprecision::backends::float128_backend237    int compare(const T& i)const
238    {
239       return m_value == i ? 0 : m_value < i ? -1 : 1;
240    }
valueboost::multiprecision::backends::float128_backend241    float128_type& value()
242    {
243       return m_value;
244    }
valueboost::multiprecision::backends::float128_backend245    const float128_type& value()const
246    {
247       return m_value;
248    }
249 };
250 
eval_add(float128_backend & result,const float128_backend & a)251 inline void eval_add(float128_backend& result, const float128_backend& a)
252 {
253    result.value() += a.value();
254 }
255 template <class A>
eval_add(float128_backend & result,const A & a)256 inline void eval_add(float128_backend& result, const A& a)
257 {
258    result.value() += a;
259 }
eval_subtract(float128_backend & result,const float128_backend & a)260 inline void eval_subtract(float128_backend& result, const float128_backend& a)
261 {
262    result.value() -= a.value();
263 }
264 template <class A>
eval_subtract(float128_backend & result,const A & a)265 inline void eval_subtract(float128_backend& result, const A& a)
266 {
267    result.value() -= a;
268 }
eval_multiply(float128_backend & result,const float128_backend & a)269 inline void eval_multiply(float128_backend& result, const float128_backend& a)
270 {
271    result.value() *= a.value();
272 }
273 template <class A>
eval_multiply(float128_backend & result,const A & a)274 inline void eval_multiply(float128_backend& result, const A& a)
275 {
276    result.value() *= a;
277 }
eval_divide(float128_backend & result,const float128_backend & a)278 inline void eval_divide(float128_backend& result, const float128_backend& a)
279 {
280    result.value() /= a.value();
281 }
282 template <class A>
eval_divide(float128_backend & result,const A & a)283 inline void eval_divide(float128_backend& result, const A& a)
284 {
285    result.value() /= a;
286 }
287 
eval_add(float128_backend & result,const float128_backend & a,const float128_backend & b)288 inline void eval_add(float128_backend& result, const float128_backend& a, const float128_backend& b)
289 {
290    result.value() = a.value() + b.value();
291 }
292 template <class A>
eval_add(float128_backend & result,const float128_backend & a,const A & b)293 inline void eval_add(float128_backend& result, const float128_backend& a, const A& b)
294 {
295    result.value() = a.value() + b;
296 }
eval_subtract(float128_backend & result,const float128_backend & a,const float128_backend & b)297 inline void eval_subtract(float128_backend& result, const float128_backend& a, const float128_backend& b)
298 {
299    result.value() = a.value() - b.value();
300 }
301 template <class A>
eval_subtract(float128_backend & result,const float128_backend & a,const A & b)302 inline void eval_subtract(float128_backend& result, const float128_backend& a, const A& b)
303 {
304    result.value() = a.value() - b;
305 }
306 template <class A>
eval_subtract(float128_backend & result,const A & a,const float128_backend & b)307 inline void eval_subtract(float128_backend& result, const A& a, const float128_backend& b)
308 {
309    result.value() = a - b.value();
310 }
eval_multiply(float128_backend & result,const float128_backend & a,const float128_backend & b)311 inline void eval_multiply(float128_backend& result, const float128_backend& a, const float128_backend& b)
312 {
313    result.value() = a.value() * b.value();
314 }
315 template <class A>
eval_multiply(float128_backend & result,const float128_backend & a,const A & b)316 inline void eval_multiply(float128_backend& result, const float128_backend& a, const A& b)
317 {
318    result.value() = a.value() * b;
319 }
eval_divide(float128_backend & result,const float128_backend & a,const float128_backend & b)320 inline void eval_divide(float128_backend& result, const float128_backend& a, const float128_backend& b)
321 {
322    result.value() = a.value() / b.value();
323 }
324 
325 template <class R>
eval_convert_to(R * result,const float128_backend & val)326 inline void eval_convert_to(R* result, const float128_backend& val)
327 {
328    *result = static_cast<R>(val.value());
329 }
330 
eval_frexp(float128_backend & result,const float128_backend & arg,int * exp)331 inline void eval_frexp(float128_backend& result, const float128_backend& arg, int* exp)
332 {
333    result.value() = frexpq(arg.value(), exp);
334 }
335 
eval_ldexp(float128_backend & result,const float128_backend & arg,int exp)336 inline void eval_ldexp(float128_backend& result, const float128_backend& arg, int exp)
337 {
338    result.value() = ldexpq(arg.value(), exp);
339 }
340 
eval_floor(float128_backend & result,const float128_backend & arg)341 inline void eval_floor(float128_backend& result, const float128_backend& arg)
342 {
343    result.value() = floorq(arg.value());
344 }
eval_ceil(float128_backend & result,const float128_backend & arg)345 inline void eval_ceil(float128_backend& result, const float128_backend& arg)
346 {
347    result.value() = ceilq(arg.value());
348 }
eval_sqrt(float128_backend & result,const float128_backend & arg)349 inline void eval_sqrt(float128_backend& result, const float128_backend& arg)
350 {
351    result.value() = sqrtq(arg.value());
352 }
eval_fpclassify(const float128_backend & arg)353 inline int eval_fpclassify(const float128_backend& arg)
354 {
355    if(isnanq(arg.value()))
356       return FP_NAN;
357    else if(isinfq(arg.value()))
358       return FP_INFINITE;
359    else if(arg.value() == 0)
360       return FP_ZERO;
361 
362    float128_backend t(arg);
363    if(t.value() < 0)
364       t.negate();
365    if(t.value() < 3.36210314311209350626267781732175260e-4932Q)
366       return FP_SUBNORMAL;
367    return FP_NORMAL;
368 }
369 
eval_increment(float128_backend & arg)370 inline void eval_increment(float128_backend& arg)
371 {
372    ++arg.value();
373 }
eval_decrement(float128_backend & arg)374 inline void eval_decrement(float128_backend& arg)
375 {
376    --arg.value();
377 }
378 
379 /*********************************************************************
380 *
381 * abs/fabs:
382 *
383 *********************************************************************/
384 
eval_abs(float128_backend & result,const float128_backend & arg)385 inline void eval_abs(float128_backend& result, const float128_backend& arg)
386 {
387    result.value() = fabsq(arg.value());
388 }
eval_fabs(float128_backend & result,const float128_backend & arg)389 inline void eval_fabs(float128_backend& result, const float128_backend& arg)
390 {
391    result.value() = fabsq(arg.value());
392 }
393 
394 /*********************************************************************
395 *
396 * Floating point functions:
397 *
398 *********************************************************************/
399 
eval_trunc(float128_backend & result,const float128_backend & arg)400 inline void eval_trunc(float128_backend& result, const float128_backend& arg)
401 {
402    if(isnanq(arg.value()) || isinfq(arg.value()))
403    {
404       result = boost::math::policies::raise_rounding_error(
405             "boost::multiprecision::trunc<%1%>(%1%)", 0,
406             number<float128_backend, et_off>(arg),
407             number<float128_backend, et_off>(arg),
408             boost::math::policies::policy<>()).backend();
409       return;
410    }
411    result.value() = truncq(arg.value());
412 }
413 /*
414 //
415 // This doesn't actually work... rely on our own default version instead.
416 //
417 inline void eval_round(float128_backend& result, const float128_backend& arg)
418 {
419    if(isnanq(arg.value()) || isinf(arg.value()))
420    {
421       result = boost::math::policies::raise_rounding_error(
422             "boost::multiprecision::trunc<%1%>(%1%)", 0,
423             number<float128_backend, et_off>(arg),
424             number<float128_backend, et_off>(arg),
425             boost::math::policies::policy<>()).backend();
426       return;
427    }
428    result.value() = roundq(arg.value());
429 }
430 */
431 
eval_exp(float128_backend & result,const float128_backend & arg)432 inline void eval_exp(float128_backend& result, const float128_backend& arg)
433 {
434    result.value() = expq(arg.value());
435 }
eval_log(float128_backend & result,const float128_backend & arg)436 inline void eval_log(float128_backend& result, const float128_backend& arg)
437 {
438    result.value() = logq(arg.value());
439 }
eval_log10(float128_backend & result,const float128_backend & arg)440 inline void eval_log10(float128_backend& result, const float128_backend& arg)
441 {
442    result.value() = log10q(arg.value());
443 }
eval_sin(float128_backend & result,const float128_backend & arg)444 inline void eval_sin(float128_backend& result, const float128_backend& arg)
445 {
446    result.value() = sinq(arg.value());
447 }
eval_cos(float128_backend & result,const float128_backend & arg)448 inline void eval_cos(float128_backend& result, const float128_backend& arg)
449 {
450    result.value() = cosq(arg.value());
451 }
eval_tan(float128_backend & result,const float128_backend & arg)452 inline void eval_tan(float128_backend& result, const float128_backend& arg)
453 {
454    result.value() = tanq(arg.value());
455 }
eval_asin(float128_backend & result,const float128_backend & arg)456 inline void eval_asin(float128_backend& result, const float128_backend& arg)
457 {
458    result.value() = asinq(arg.value());
459 }
eval_acos(float128_backend & result,const float128_backend & arg)460 inline void eval_acos(float128_backend& result, const float128_backend& arg)
461 {
462    result.value() = acosq(arg.value());
463 }
eval_atan(float128_backend & result,const float128_backend & arg)464 inline void eval_atan(float128_backend& result, const float128_backend& arg)
465 {
466    result.value() = atanq(arg.value());
467 }
eval_sinh(float128_backend & result,const float128_backend & arg)468 inline void eval_sinh(float128_backend& result, const float128_backend& arg)
469 {
470    result.value() = sinhq(arg.value());
471 }
eval_cosh(float128_backend & result,const float128_backend & arg)472 inline void eval_cosh(float128_backend& result, const float128_backend& arg)
473 {
474    result.value() = coshq(arg.value());
475 }
eval_tanh(float128_backend & result,const float128_backend & arg)476 inline void eval_tanh(float128_backend& result, const float128_backend& arg)
477 {
478    result.value() = tanhq(arg.value());
479 }
eval_fmod(float128_backend & result,const float128_backend & a,const float128_backend & b)480 inline void eval_fmod(float128_backend& result, const float128_backend& a, const float128_backend& b)
481 {
482    result.value() = fmodq(a.value(), b.value());
483 }
eval_pow(float128_backend & result,const float128_backend & a,const float128_backend & b)484 inline void eval_pow(float128_backend& result, const float128_backend& a, const float128_backend& b)
485 {
486    result.value() = powq(a.value(), b.value());
487 }
eval_atan2(float128_backend & result,const float128_backend & a,const float128_backend & b)488 inline void eval_atan2(float128_backend& result, const float128_backend& a, const float128_backend& b)
489 {
490    result.value() = atan2q(a.value(), b.value());
491 }
eval_multiply_add(float128_backend & result,const float128_backend & a,const float128_backend & b,const float128_backend & c)492 inline void eval_multiply_add(float128_backend& result, const float128_backend& a, const float128_backend& b, const float128_backend& c)
493 {
494    result.value() = fmaq(a.value(), b.value(), c.value());
495 }
496 
hash_value(const float128_backend & val)497 inline std::size_t hash_value(const float128_backend& val)
498 {
499    return  boost::hash_value(static_cast<double>(val.value()));
500 }
501 
502 } // namespace backends
503 
504    template<boost::multiprecision::expression_template_option ExpressionTemplates>
BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend,ExpressionTemplates> & arg)505    inline boost::multiprecision::number<float128_backend, ExpressionTemplates> asinh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg)
506    {
507       return asinhq(arg.backend().value());
508    }
509    template<boost::multiprecision::expression_template_option ExpressionTemplates>
BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend,ExpressionTemplates> & arg)510    inline boost::multiprecision::number<float128_backend, ExpressionTemplates> acosh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg)
511    {
512       return acoshq(arg.backend().value());
513    }
514    template<boost::multiprecision::expression_template_option ExpressionTemplates>
BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend,ExpressionTemplates> & arg)515    inline boost::multiprecision::number<float128_backend, ExpressionTemplates> atanh BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg)
516    {
517       return atanhq(arg.backend().value());
518    }
519    template<boost::multiprecision::expression_template_option ExpressionTemplates>
BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend,ExpressionTemplates> & arg)520    inline boost::multiprecision::number<float128_backend, ExpressionTemplates> cbrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg)
521    {
522       return cbrtq(arg.backend().value());
523    }
524    template<boost::multiprecision::expression_template_option ExpressionTemplates>
BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend,ExpressionTemplates> & arg)525    inline boost::multiprecision::number<float128_backend, ExpressionTemplates> erf BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg)
526    {
527       return erfq(arg.backend().value());
528    }
529    template<boost::multiprecision::expression_template_option ExpressionTemplates>
BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend,ExpressionTemplates> & arg)530    inline boost::multiprecision::number<float128_backend, ExpressionTemplates> erfc BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg)
531    {
532       return erfcq(arg.backend().value());
533    }
534    template<boost::multiprecision::expression_template_option ExpressionTemplates>
BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend,ExpressionTemplates> & arg)535    inline boost::multiprecision::number<float128_backend, ExpressionTemplates> expm1 BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg)
536    {
537       return expm1q(arg.backend().value());
538    }
539    template<boost::multiprecision::expression_template_option ExpressionTemplates>
BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend,ExpressionTemplates> & arg)540    inline boost::multiprecision::number<float128_backend, ExpressionTemplates> lgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg)
541    {
542       return lgammaq(arg.backend().value());
543    }
544    template<boost::multiprecision::expression_template_option ExpressionTemplates>
BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend,ExpressionTemplates> & arg)545    inline boost::multiprecision::number<float128_backend, ExpressionTemplates> tgamma BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg)
546    {
547       return tgammaq(arg.backend().value());
548    }
549    template<boost::multiprecision::expression_template_option ExpressionTemplates>
BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend,ExpressionTemplates> & arg)550    inline boost::multiprecision::number<float128_backend, ExpressionTemplates> log1p BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<float128_backend, ExpressionTemplates>& arg)
551    {
552       return log1pq(arg.backend().value());
553    }
554 
555    template <multiprecision::expression_template_option ExpressionTemplates>
BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::float128_backend,ExpressionTemplates> & arg)556    inline int signbit BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates>& arg)
557    {
558       return ::signbitq(arg.backend().value());
559    }
560 
561    template <multiprecision::expression_template_option ExpressionTemplates>
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)562    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)
563    {
564       return ::copysignq(a.backend().value(), b.backend().value());
565    }
566 
eval_remainder(float128_backend & result,const float128_backend & a,const float128_backend & b)567    inline void eval_remainder(float128_backend& result, const float128_backend& a, const float128_backend& b)
568    {
569       result.value() = remainderq(a.value(), b.value());
570    }
eval_remainder(float128_backend & result,const float128_backend & a,const float128_backend & b,int * pi)571    inline void eval_remainder(float128_backend& result, const float128_backend& a, const float128_backend& b, int* pi)
572    {
573       result.value() = remquoq(a.value(), b.value(), pi);
574    }
575 
576 } // namespace multiprecision
577 
578 namespace math {
579 
580    using boost::multiprecision::signbit;
581    using boost::multiprecision::copysign;
582 
583 } // namespace math
584 
585 } // namespace boost
586 
587 namespace boost{
588 namespace archive{
589 
590 class binary_oarchive;
591 class binary_iarchive;
592 
593 }
594 
595 namespace serialization{ namespace float128_detail{
596 
597 template <class Archive>
do_serialize(Archive & ar,boost::multiprecision::backends::float128_backend & val,const mpl::false_ &,const mpl::false_ &)598 void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const mpl::false_&, const mpl::false_&)
599 {
600    // saving
601    // non-binary
602    std::string s(val.str(0, std::ios_base::scientific));
603    ar & s;
604 }
605 template <class Archive>
do_serialize(Archive & ar,boost::multiprecision::backends::float128_backend & val,const mpl::true_ &,const mpl::false_ &)606 void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const mpl::true_&, const mpl::false_&)
607 {
608    // loading
609    // non-binary
610    std::string s;
611    ar & s;
612    val = s.c_str();
613 }
614 
615 template <class Archive>
do_serialize(Archive & ar,boost::multiprecision::backends::float128_backend & val,const mpl::false_ &,const mpl::true_ &)616 void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const mpl::false_&, const mpl::true_&)
617 {
618    // saving
619    // binary
620    ar.save_binary(&val, sizeof(val));
621 }
622 template <class Archive>
do_serialize(Archive & ar,boost::multiprecision::backends::float128_backend & val,const mpl::true_ &,const mpl::true_ &)623 void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const mpl::true_&, const mpl::true_&)
624 {
625    // loading
626    // binary
627    ar.load_binary(&val, sizeof(val));
628 }
629 
630 } // detail
631 
632 template <class Archive>
serialize(Archive & ar,boost::multiprecision::backends::float128_backend & val,unsigned int)633 void serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, unsigned int /*version*/)
634 {
635    typedef typename Archive::is_loading load_tag;
636    typedef typename mpl::bool_<boost::is_same<Archive, boost::archive::binary_oarchive>::value || boost::is_same<Archive, boost::archive::binary_iarchive>::value> binary_tag;
637 
638    float128_detail::do_serialize(ar, val, load_tag(), binary_tag());
639 }
640 
641 } // namepsace archive
642 
643 } // namespace boost
644 
645 namespace std{
646 
647 template <boost::multiprecision::expression_template_option ExpressionTemplates>
648 class numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >
649 {
650    typedef boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> number_type;
651 public:
652    BOOST_STATIC_CONSTEXPR bool is_specialized = true;
number_type(min)653    static number_type (min)() BOOST_NOEXCEPT { return 3.36210314311209350626267781732175260e-4932Q; }
number_type(max)654    static number_type (max)() BOOST_NOEXCEPT { return 1.18973149535723176508575932662800702e4932Q; }
lowest()655    static number_type lowest() BOOST_NOEXCEPT { return -(max)(); }
656    BOOST_STATIC_CONSTEXPR int digits = 113;
657    BOOST_STATIC_CONSTEXPR int digits10 = 33;
658    BOOST_STATIC_CONSTEXPR int max_digits10 = 36;
659    BOOST_STATIC_CONSTEXPR bool is_signed = true;
660    BOOST_STATIC_CONSTEXPR bool is_integer = false;
661    BOOST_STATIC_CONSTEXPR bool is_exact = false;
662    BOOST_STATIC_CONSTEXPR int radix = 2;
epsilon()663    static number_type epsilon() { return 1.92592994438723585305597794258492732e-34Q; }
round_error()664    static number_type round_error() { return 0.5; }
665    BOOST_STATIC_CONSTEXPR int min_exponent = -16381;
666    BOOST_STATIC_CONSTEXPR int min_exponent10 = min_exponent * 301L / 1000L;
667    BOOST_STATIC_CONSTEXPR int max_exponent = 16384;
668    BOOST_STATIC_CONSTEXPR int max_exponent10 = max_exponent * 301L / 1000L;
669    BOOST_STATIC_CONSTEXPR bool has_infinity = true;
670    BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true;
671    BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
672    BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_present;
673    BOOST_STATIC_CONSTEXPR bool has_denorm_loss = true;
infinity()674    static number_type infinity() { return 1.0q / 0.0q; }
quiet_NaN()675    static number_type quiet_NaN() { return number_type("nan"); }
signaling_NaN()676    static number_type signaling_NaN() { return 0; }
denorm_min()677    static number_type denorm_min() { return 6.475175119438025110924438958227646552e-4966Q; }
678    BOOST_STATIC_CONSTEXPR bool is_iec559 = true;
679    BOOST_STATIC_CONSTEXPR bool is_bounded = false;
680    BOOST_STATIC_CONSTEXPR bool is_modulo = false;
681    BOOST_STATIC_CONSTEXPR bool traps = false;
682    BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
683    BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest;
684 };
685 
686 template <boost::multiprecision::expression_template_option ExpressionTemplates>
687 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_specialized;
688 template <boost::multiprecision::expression_template_option ExpressionTemplates>
689 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits;
690 template <boost::multiprecision::expression_template_option ExpressionTemplates>
691 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits10;
692 template <boost::multiprecision::expression_template_option ExpressionTemplates>
693 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_digits10;
694 
695 template <boost::multiprecision::expression_template_option ExpressionTemplates>
696 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_signed;
697 template <boost::multiprecision::expression_template_option ExpressionTemplates>
698 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_integer;
699 template <boost::multiprecision::expression_template_option ExpressionTemplates>
700 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_exact;
701 template <boost::multiprecision::expression_template_option ExpressionTemplates>
702 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::radix;
703 
704 
705 template <boost::multiprecision::expression_template_option ExpressionTemplates>
706 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent;
707 template <boost::multiprecision::expression_template_option ExpressionTemplates>
708 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent;
709 template <boost::multiprecision::expression_template_option ExpressionTemplates>
710 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent10;
711 template <boost::multiprecision::expression_template_option ExpressionTemplates>
712 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent10;
713 
714 template <boost::multiprecision::expression_template_option ExpressionTemplates>
715 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_infinity;
716 template <boost::multiprecision::expression_template_option ExpressionTemplates>
717 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_quiet_NaN;
718 template <boost::multiprecision::expression_template_option ExpressionTemplates>
719 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_signaling_NaN;
720 template <boost::multiprecision::expression_template_option ExpressionTemplates>
721 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_denorm_loss;
722 
723 template <boost::multiprecision::expression_template_option ExpressionTemplates>
724 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_iec559;
725 template <boost::multiprecision::expression_template_option ExpressionTemplates>
726 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_bounded;
727 template <boost::multiprecision::expression_template_option ExpressionTemplates>
728 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_modulo;
729 template <boost::multiprecision::expression_template_option ExpressionTemplates>
730 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::traps;
731 template <boost::multiprecision::expression_template_option ExpressionTemplates>
732 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::tinyness_before;
733 
734 template <boost::multiprecision::expression_template_option ExpressionTemplates>
735 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::round_style;
736 template <boost::multiprecision::expression_template_option ExpressionTemplates>
737 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_denorm;
738 
739 } // namespace std
740 
741 
742 #endif
743