Chris@16
|
1 ///////////////////////////////////////////////////////////////
|
Chris@16
|
2 // Copyright 2013 John Maddock. Distributed under the Boost
|
Chris@16
|
3 // Software License, Version 1.0. (See accompanying file
|
Chris@16
|
4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
|
Chris@16
|
5
|
Chris@16
|
6 #ifndef BOOST_MP_FLOAT128_HPP
|
Chris@16
|
7 #define BOOST_MP_FLOAT128_HPP
|
Chris@16
|
8
|
Chris@16
|
9 #include <boost/config.hpp>
|
Chris@16
|
10 #include <boost/scoped_array.hpp>
|
Chris@16
|
11 #include <boost/multiprecision/number.hpp>
|
Chris@16
|
12
|
Chris@16
|
13 #if defined(BOOST_INTEL) && !defined(BOOST_MP_USE_FLOAT128) && !defined(BOOST_MP_USE_QUAD)
|
Chris@16
|
14 # if defined(BOOST_INTEL_CXX_VERSION) && (BOOST_INTEL_CXX_VERSION >= 1310) && defined(__GNUC__)
|
Chris@16
|
15 # if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6))
|
Chris@16
|
16 # define BOOST_MP_USE_FLOAT128
|
Chris@16
|
17 # endif
|
Chris@16
|
18 # endif
|
Chris@16
|
19
|
Chris@16
|
20 # ifndef BOOST_MP_USE_FLOAT128
|
Chris@16
|
21 # define BOOST_MP_USE_QUAD
|
Chris@16
|
22 # endif
|
Chris@16
|
23 #endif
|
Chris@16
|
24
|
Chris@16
|
25 #if defined(__GNUC__) && !defined(BOOST_MP_USE_FLOAT128) && !defined(BOOST_MP_USE_QUAD)
|
Chris@16
|
26 # define BOOST_MP_USE_FLOAT128
|
Chris@16
|
27 #endif
|
Chris@16
|
28
|
Chris@16
|
29 #if !defined(BOOST_MP_USE_FLOAT128) && !defined(BOOST_MP_USE_QUAD)
|
Chris@16
|
30 # error "Sorry compiler is neither GCC, not Intel, don't know how to configure this header."
|
Chris@16
|
31 #endif
|
Chris@16
|
32 #if defined(BOOST_MP_USE_FLOAT128) && defined(BOOST_MP_USE_QUAD)
|
Chris@16
|
33 # error "Oh dear, both BOOST_MP_USE_FLOAT128 and BOOST_MP_USE_QUAD are defined, which one should I be using?"
|
Chris@16
|
34 #endif
|
Chris@16
|
35
|
Chris@16
|
36 #if defined(BOOST_MP_USE_FLOAT128)
|
Chris@16
|
37
|
Chris@16
|
38 extern "C" {
|
Chris@16
|
39 #include <quadmath.h>
|
Chris@16
|
40 }
|
Chris@16
|
41
|
Chris@16
|
42 typedef __float128 float128_type;
|
Chris@16
|
43
|
Chris@16
|
44 #elif defined(BOOST_MP_USE_QUAD)
|
Chris@16
|
45
|
Chris@16
|
46 #include <boost/multiprecision/detail/float_string_cvt.hpp>
|
Chris@16
|
47
|
Chris@16
|
48 typedef _Quad float128_type;
|
Chris@16
|
49
|
Chris@16
|
50 extern "C" {
|
Chris@16
|
51 _Quad __ldexpq(_Quad, int);
|
Chris@16
|
52 _Quad __frexpq(_Quad, int*);
|
Chris@16
|
53 _Quad __fabsq(_Quad);
|
Chris@16
|
54 _Quad __floorq(_Quad);
|
Chris@16
|
55 _Quad __ceilq(_Quad);
|
Chris@16
|
56 _Quad __sqrtq(_Quad);
|
Chris@16
|
57 _Quad __truncq(_Quad);
|
Chris@16
|
58 _Quad __expq(_Quad);
|
Chris@16
|
59 _Quad __powq(_Quad, _Quad);
|
Chris@16
|
60 _Quad __logq(_Quad);
|
Chris@16
|
61 _Quad __log10q(_Quad);
|
Chris@16
|
62 _Quad __sinq(_Quad);
|
Chris@16
|
63 _Quad __cosq(_Quad);
|
Chris@16
|
64 _Quad __tanq(_Quad);
|
Chris@16
|
65 _Quad __asinq(_Quad);
|
Chris@16
|
66 _Quad __acosq(_Quad);
|
Chris@16
|
67 _Quad __atanq(_Quad);
|
Chris@16
|
68 _Quad __sinhq(_Quad);
|
Chris@16
|
69 _Quad __coshq(_Quad);
|
Chris@16
|
70 _Quad __tanhq(_Quad);
|
Chris@16
|
71 _Quad __fmodq(_Quad, _Quad);
|
Chris@16
|
72 _Quad __atan2q(_Quad, _Quad);
|
Chris@16
|
73
|
Chris@16
|
74 #define ldexpq __ldexpq
|
Chris@16
|
75 #define frexpq __frexpq
|
Chris@16
|
76 #define fabsq __fabsq
|
Chris@16
|
77 #define floorq __floorq
|
Chris@16
|
78 #define ceilq __ceilq
|
Chris@16
|
79 #define sqrtq __sqrtq
|
Chris@16
|
80 #define truncq __truncq
|
Chris@16
|
81 #define expq __expq
|
Chris@16
|
82 #define powq __powq
|
Chris@16
|
83 #define logq __logq
|
Chris@16
|
84 #define log10q __log10q
|
Chris@16
|
85 #define sinq __sinq
|
Chris@16
|
86 #define cosq __cosq
|
Chris@16
|
87 #define tanq __tanq
|
Chris@16
|
88 #define asinq __asinq
|
Chris@16
|
89 #define acosq __acosq
|
Chris@16
|
90 #define atanq __atanq
|
Chris@16
|
91 #define sinhq __sinhq
|
Chris@16
|
92 #define coshq __coshq
|
Chris@16
|
93 #define tanhq __tanhq
|
Chris@16
|
94 #define fmodq __fmodq
|
Chris@16
|
95 #define atan2q __atan2q
|
Chris@16
|
96 }
|
Chris@16
|
97
|
Chris@16
|
98 inline _Quad isnanq(_Quad v)
|
Chris@16
|
99 {
|
Chris@16
|
100 return v != v;
|
Chris@16
|
101 }
|
Chris@16
|
102 inline _Quad isinfq(_Quad v)
|
Chris@16
|
103 {
|
Chris@16
|
104 return __fabsq(v) > 1.18973149535723176508575932662800702e4932Q;
|
Chris@16
|
105 }
|
Chris@16
|
106
|
Chris@16
|
107 #endif
|
Chris@16
|
108
|
Chris@16
|
109 namespace boost{
|
Chris@16
|
110 namespace multiprecision{
|
Chris@16
|
111 namespace backends{
|
Chris@16
|
112
|
Chris@16
|
113 struct float128_backend;
|
Chris@16
|
114
|
Chris@16
|
115 }
|
Chris@16
|
116
|
Chris@16
|
117 using backends::float128_backend;
|
Chris@16
|
118
|
Chris@16
|
119 template<>
|
Chris@16
|
120 struct number_category<backends::float128_backend> : public mpl::int_<number_kind_floating_point> {};
|
Chris@16
|
121 template<>
|
Chris@16
|
122 struct number_category<float128_type> : public mpl::int_<number_kind_floating_point> {};
|
Chris@16
|
123
|
Chris@16
|
124 typedef number<float128_backend, et_off> float128;
|
Chris@16
|
125
|
Chris@16
|
126 namespace backends{
|
Chris@16
|
127
|
Chris@16
|
128 struct float128_backend
|
Chris@16
|
129 {
|
Chris@16
|
130 typedef mpl::list<signed char, short, int, long, long long> signed_types;
|
Chris@16
|
131 typedef mpl::list<unsigned char, unsigned short,
|
Chris@16
|
132 unsigned int, unsigned long, unsigned long long> unsigned_types;
|
Chris@16
|
133 typedef mpl::list<float, double, long double> float_types;
|
Chris@16
|
134 typedef int exponent_type;
|
Chris@16
|
135
|
Chris@16
|
136 private:
|
Chris@16
|
137 float128_type m_value;
|
Chris@16
|
138 public:
|
Chris@101
|
139 BOOST_CONSTEXPR float128_backend() BOOST_NOEXCEPT : m_value(0) {}
|
Chris@101
|
140 BOOST_CONSTEXPR float128_backend(const float128_backend& o) BOOST_NOEXCEPT : m_value(o.m_value) {}
|
Chris@101
|
141 float128_backend& operator = (const float128_backend& o) BOOST_NOEXCEPT
|
Chris@16
|
142 {
|
Chris@16
|
143 m_value = o.m_value;
|
Chris@16
|
144 return *this;
|
Chris@16
|
145 }
|
Chris@16
|
146 template <class T>
|
Chris@101
|
147 BOOST_CONSTEXPR float128_backend(const T& i, const typename enable_if_c<is_convertible<T, float128_type>::value>::type* = 0) BOOST_NOEXCEPT
|
Chris@16
|
148 : m_value(i) {}
|
Chris@16
|
149 template <class T>
|
Chris@101
|
150 typename enable_if_c<is_arithmetic<T>::value || is_convertible<T, float128_type>::value, float128_backend&>::type operator = (const T& i) BOOST_NOEXCEPT
|
Chris@16
|
151 {
|
Chris@16
|
152 m_value = i;
|
Chris@16
|
153 return *this;
|
Chris@16
|
154 }
|
Chris@16
|
155 float128_backend& operator = (const char* s)
|
Chris@16
|
156 {
|
Chris@16
|
157 #ifndef BOOST_MP_USE_QUAD
|
Chris@16
|
158 char* p_end;
|
Chris@16
|
159 m_value = strtoflt128(s, &p_end);
|
Chris@16
|
160 if(p_end - s != (std::ptrdiff_t)std::strlen(s))
|
Chris@16
|
161 {
|
Chris@16
|
162 BOOST_THROW_EXCEPTION(std::runtime_error("Unable to interpret input string as a floating point value"));
|
Chris@16
|
163 }
|
Chris@16
|
164 #else
|
Chris@101
|
165 boost::multiprecision::detail::convert_from_string(*this, s);
|
Chris@16
|
166 #endif
|
Chris@16
|
167 return *this;
|
Chris@16
|
168 }
|
Chris@101
|
169 void swap(float128_backend& o) BOOST_NOEXCEPT
|
Chris@16
|
170 {
|
Chris@16
|
171 std::swap(m_value, o.value());
|
Chris@16
|
172 }
|
Chris@16
|
173 std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
|
Chris@16
|
174 {
|
Chris@16
|
175 #ifndef BOOST_MP_USE_QUAD
|
Chris@16
|
176 char buf[100];
|
Chris@16
|
177 boost::scoped_array<char> buf2;
|
Chris@16
|
178 std::string format = "%";
|
Chris@16
|
179 if(f & std::ios_base::showpos)
|
Chris@16
|
180 format += "+";
|
Chris@16
|
181 if(f & std::ios_base::showpoint)
|
Chris@16
|
182 format += "#";
|
Chris@16
|
183 format += ".*";
|
Chris@16
|
184 if(digits == 0)
|
Chris@16
|
185 digits = 36;
|
Chris@16
|
186 format += "Q";
|
Chris@16
|
187 if(f & std::ios_base::scientific)
|
Chris@16
|
188 format += "e";
|
Chris@16
|
189 else if(f & std::ios_base::fixed)
|
Chris@16
|
190 format += "f";
|
Chris@16
|
191 else
|
Chris@16
|
192 format += "g";
|
Chris@16
|
193
|
Chris@16
|
194 int v = quadmath_snprintf (buf, 100, format.c_str(), digits, m_value);
|
Chris@16
|
195
|
Chris@16
|
196 if((v < 0) || (v >= 99))
|
Chris@16
|
197 {
|
Chris@16
|
198 int v_max = v;
|
Chris@16
|
199 buf2.reset(new char[v+3]);
|
Chris@16
|
200 v = quadmath_snprintf (&buf2[0], v_max + 3, format.c_str(), digits, m_value);
|
Chris@16
|
201 if(v >= v_max + 3)
|
Chris@16
|
202 {
|
Chris@16
|
203 BOOST_THROW_EXCEPTION(std::runtime_error("Formatting of float128_type failed."));
|
Chris@16
|
204 }
|
Chris@16
|
205 return &buf2[0];
|
Chris@16
|
206 }
|
Chris@16
|
207 return buf;
|
Chris@16
|
208 #else
|
Chris@101
|
209 return boost::multiprecision::detail::convert_to_string(*this, digits ? digits : 37, f);
|
Chris@16
|
210 #endif
|
Chris@16
|
211 }
|
Chris@101
|
212 void negate() BOOST_NOEXCEPT
|
Chris@16
|
213 {
|
Chris@16
|
214 m_value = -m_value;
|
Chris@16
|
215 }
|
Chris@16
|
216 int compare(const float128_backend& o)const
|
Chris@16
|
217 {
|
Chris@16
|
218 return m_value == o.m_value ? 0 : m_value < o.m_value ? -1 : 1;
|
Chris@16
|
219 }
|
Chris@16
|
220 template <class T>
|
Chris@16
|
221 int compare(const T& i)const
|
Chris@16
|
222 {
|
Chris@16
|
223 return m_value == i ? 0 : m_value < i ? -1 : 1;
|
Chris@16
|
224 }
|
Chris@16
|
225 float128_type& value()
|
Chris@16
|
226 {
|
Chris@16
|
227 return m_value;
|
Chris@16
|
228 }
|
Chris@16
|
229 const float128_type& value()const
|
Chris@16
|
230 {
|
Chris@16
|
231 return m_value;
|
Chris@16
|
232 }
|
Chris@16
|
233 };
|
Chris@16
|
234
|
Chris@16
|
235 inline void eval_add(float128_backend& result, const float128_backend& a)
|
Chris@16
|
236 {
|
Chris@16
|
237 result.value() += a.value();
|
Chris@16
|
238 }
|
Chris@16
|
239 template <class A>
|
Chris@16
|
240 inline void eval_add(float128_backend& result, const A& a)
|
Chris@16
|
241 {
|
Chris@16
|
242 result.value() += a;
|
Chris@16
|
243 }
|
Chris@16
|
244 inline void eval_subtract(float128_backend& result, const float128_backend& a)
|
Chris@16
|
245 {
|
Chris@16
|
246 result.value() -= a.value();
|
Chris@16
|
247 }
|
Chris@16
|
248 template <class A>
|
Chris@16
|
249 inline void eval_subtract(float128_backend& result, const A& a)
|
Chris@16
|
250 {
|
Chris@16
|
251 result.value() -= a;
|
Chris@16
|
252 }
|
Chris@16
|
253 inline void eval_multiply(float128_backend& result, const float128_backend& a)
|
Chris@16
|
254 {
|
Chris@16
|
255 result.value() *= a.value();
|
Chris@16
|
256 }
|
Chris@16
|
257 template <class A>
|
Chris@16
|
258 inline void eval_multiply(float128_backend& result, const A& a)
|
Chris@16
|
259 {
|
Chris@16
|
260 result.value() *= a;
|
Chris@16
|
261 }
|
Chris@16
|
262 inline void eval_divide(float128_backend& result, const float128_backend& a)
|
Chris@16
|
263 {
|
Chris@16
|
264 result.value() /= a.value();
|
Chris@16
|
265 }
|
Chris@16
|
266 template <class A>
|
Chris@16
|
267 inline void eval_divide(float128_backend& result, const A& a)
|
Chris@16
|
268 {
|
Chris@16
|
269 result.value() /= a;
|
Chris@16
|
270 }
|
Chris@16
|
271
|
Chris@16
|
272 inline void eval_add(float128_backend& result, const float128_backend& a, const float128_backend& b)
|
Chris@16
|
273 {
|
Chris@16
|
274 result.value() = a.value() + b.value();
|
Chris@16
|
275 }
|
Chris@16
|
276 template <class A>
|
Chris@16
|
277 inline void eval_add(float128_backend& result, const float128_backend& a, const A& b)
|
Chris@16
|
278 {
|
Chris@16
|
279 result.value() = a.value() + b;
|
Chris@16
|
280 }
|
Chris@16
|
281 inline void eval_subtract(float128_backend& result, const float128_backend& a, const float128_backend& b)
|
Chris@16
|
282 {
|
Chris@16
|
283 result.value() = a.value() - b.value();
|
Chris@16
|
284 }
|
Chris@16
|
285 template <class A>
|
Chris@16
|
286 inline void eval_subtract(float128_backend& result, const float128_backend& a, const A& b)
|
Chris@16
|
287 {
|
Chris@16
|
288 result.value() = a.value() - b;
|
Chris@16
|
289 }
|
Chris@16
|
290 template <class A>
|
Chris@16
|
291 inline void eval_subtract(float128_backend& result, const A& a, const float128_backend& b)
|
Chris@16
|
292 {
|
Chris@16
|
293 result.value() = a - b.value();
|
Chris@16
|
294 }
|
Chris@16
|
295 inline void eval_multiply(float128_backend& result, const float128_backend& a, const float128_backend& b)
|
Chris@16
|
296 {
|
Chris@16
|
297 result.value() = a.value() * b.value();
|
Chris@16
|
298 }
|
Chris@16
|
299 template <class A>
|
Chris@16
|
300 inline void eval_multiply(float128_backend& result, const float128_backend& a, const A& b)
|
Chris@16
|
301 {
|
Chris@16
|
302 result.value() = a.value() * b;
|
Chris@16
|
303 }
|
Chris@16
|
304 inline void eval_divide(float128_backend& result, const float128_backend& a, const float128_backend& b)
|
Chris@16
|
305 {
|
Chris@16
|
306 result.value() = a.value() / b.value();
|
Chris@16
|
307 }
|
Chris@16
|
308
|
Chris@16
|
309 template <class R>
|
Chris@16
|
310 inline void eval_convert_to(R* result, const float128_backend& val)
|
Chris@16
|
311 {
|
Chris@16
|
312 *result = static_cast<R>(val.value());
|
Chris@16
|
313 }
|
Chris@16
|
314
|
Chris@16
|
315 inline void eval_frexp(float128_backend& result, const float128_backend& arg, int* exp)
|
Chris@16
|
316 {
|
Chris@16
|
317 result.value() = frexpq(arg.value(), exp);
|
Chris@16
|
318 }
|
Chris@16
|
319
|
Chris@16
|
320 inline void eval_ldexp(float128_backend& result, const float128_backend& arg, int exp)
|
Chris@16
|
321 {
|
Chris@16
|
322 result.value() = ldexpq(arg.value(), exp);
|
Chris@16
|
323 }
|
Chris@16
|
324
|
Chris@16
|
325 inline void eval_floor(float128_backend& result, const float128_backend& arg)
|
Chris@16
|
326 {
|
Chris@16
|
327 result.value() = floorq(arg.value());
|
Chris@16
|
328 }
|
Chris@16
|
329 inline void eval_ceil(float128_backend& result, const float128_backend& arg)
|
Chris@16
|
330 {
|
Chris@16
|
331 result.value() = ceilq(arg.value());
|
Chris@16
|
332 }
|
Chris@16
|
333 inline void eval_sqrt(float128_backend& result, const float128_backend& arg)
|
Chris@16
|
334 {
|
Chris@16
|
335 result.value() = sqrtq(arg.value());
|
Chris@16
|
336 }
|
Chris@16
|
337 inline int eval_fpclassify(const float128_backend& arg)
|
Chris@16
|
338 {
|
Chris@16
|
339 return isnanq(arg.value()) ? FP_NAN : isinfq(arg.value()) ? FP_INFINITE : arg.value() == 0 ? FP_ZERO : FP_NORMAL;
|
Chris@16
|
340 }
|
Chris@16
|
341
|
Chris@16
|
342 inline void eval_increment(float128_backend& arg)
|
Chris@16
|
343 {
|
Chris@16
|
344 ++arg.value();
|
Chris@16
|
345 }
|
Chris@16
|
346 inline void eval_decrement(float128_backend& arg)
|
Chris@16
|
347 {
|
Chris@16
|
348 --arg.value();
|
Chris@16
|
349 }
|
Chris@16
|
350
|
Chris@16
|
351 /*********************************************************************
|
Chris@16
|
352 *
|
Chris@16
|
353 * abs/fabs:
|
Chris@16
|
354 *
|
Chris@16
|
355 *********************************************************************/
|
Chris@16
|
356
|
Chris@16
|
357 inline void eval_abs(float128_backend& result, const float128_backend& arg)
|
Chris@16
|
358 {
|
Chris@16
|
359 result.value() = fabsq(arg.value());
|
Chris@16
|
360 }
|
Chris@16
|
361 inline void eval_fabs(float128_backend& result, const float128_backend& arg)
|
Chris@16
|
362 {
|
Chris@16
|
363 result.value() = fabsq(arg.value());
|
Chris@16
|
364 }
|
Chris@16
|
365
|
Chris@16
|
366 /*********************************************************************
|
Chris@16
|
367 *
|
Chris@16
|
368 * Floating point functions:
|
Chris@16
|
369 *
|
Chris@16
|
370 *********************************************************************/
|
Chris@16
|
371
|
Chris@16
|
372 inline void eval_trunc(float128_backend& result, const float128_backend& arg)
|
Chris@16
|
373 {
|
Chris@16
|
374 if(isnanq(arg.value()) || isinfq(arg.value()))
|
Chris@16
|
375 {
|
Chris@16
|
376 result = boost::math::policies::raise_rounding_error(
|
Chris@16
|
377 "boost::multiprecision::trunc<%1%>(%1%)", 0,
|
Chris@16
|
378 number<float128_backend, et_off>(arg),
|
Chris@16
|
379 number<float128_backend, et_off>(arg),
|
Chris@16
|
380 boost::math::policies::policy<>()).backend();
|
Chris@16
|
381 return;
|
Chris@16
|
382 }
|
Chris@16
|
383 result.value() = truncq(arg.value());
|
Chris@16
|
384 }
|
Chris@16
|
385 /*
|
Chris@16
|
386 //
|
Chris@16
|
387 // This doesn't actually work... rely on our own default version instead.
|
Chris@16
|
388 //
|
Chris@16
|
389 inline void eval_round(float128_backend& result, const float128_backend& arg)
|
Chris@16
|
390 {
|
Chris@16
|
391 if(isnanq(arg.value()) || isinf(arg.value()))
|
Chris@16
|
392 {
|
Chris@16
|
393 result = boost::math::policies::raise_rounding_error(
|
Chris@16
|
394 "boost::multiprecision::trunc<%1%>(%1%)", 0,
|
Chris@16
|
395 number<float128_backend, et_off>(arg),
|
Chris@16
|
396 number<float128_backend, et_off>(arg),
|
Chris@16
|
397 boost::math::policies::policy<>()).backend();
|
Chris@16
|
398 return;
|
Chris@16
|
399 }
|
Chris@16
|
400 result.value() = roundq(arg.value());
|
Chris@16
|
401 }
|
Chris@16
|
402 */
|
Chris@16
|
403
|
Chris@16
|
404 inline void eval_exp(float128_backend& result, const float128_backend& arg)
|
Chris@16
|
405 {
|
Chris@16
|
406 result.value() = expq(arg.value());
|
Chris@16
|
407 }
|
Chris@16
|
408 inline void eval_log(float128_backend& result, const float128_backend& arg)
|
Chris@16
|
409 {
|
Chris@16
|
410 result.value() = logq(arg.value());
|
Chris@16
|
411 }
|
Chris@16
|
412 inline void eval_log10(float128_backend& result, const float128_backend& arg)
|
Chris@16
|
413 {
|
Chris@16
|
414 result.value() = log10q(arg.value());
|
Chris@16
|
415 }
|
Chris@16
|
416 inline void eval_sin(float128_backend& result, const float128_backend& arg)
|
Chris@16
|
417 {
|
Chris@16
|
418 result.value() = sinq(arg.value());
|
Chris@16
|
419 }
|
Chris@16
|
420 inline void eval_cos(float128_backend& result, const float128_backend& arg)
|
Chris@16
|
421 {
|
Chris@16
|
422 result.value() = cosq(arg.value());
|
Chris@16
|
423 }
|
Chris@16
|
424 inline void eval_tan(float128_backend& result, const float128_backend& arg)
|
Chris@16
|
425 {
|
Chris@16
|
426 result.value() = tanq(arg.value());
|
Chris@16
|
427 }
|
Chris@16
|
428 inline void eval_asin(float128_backend& result, const float128_backend& arg)
|
Chris@16
|
429 {
|
Chris@16
|
430 result.value() = asinq(arg.value());
|
Chris@16
|
431 }
|
Chris@16
|
432 inline void eval_acos(float128_backend& result, const float128_backend& arg)
|
Chris@16
|
433 {
|
Chris@16
|
434 result.value() = acosq(arg.value());
|
Chris@16
|
435 }
|
Chris@16
|
436 inline void eval_atan(float128_backend& result, const float128_backend& arg)
|
Chris@16
|
437 {
|
Chris@16
|
438 result.value() = atanq(arg.value());
|
Chris@16
|
439 }
|
Chris@16
|
440 inline void eval_sinh(float128_backend& result, const float128_backend& arg)
|
Chris@16
|
441 {
|
Chris@16
|
442 result.value() = sinhq(arg.value());
|
Chris@16
|
443 }
|
Chris@16
|
444 inline void eval_cosh(float128_backend& result, const float128_backend& arg)
|
Chris@16
|
445 {
|
Chris@16
|
446 result.value() = coshq(arg.value());
|
Chris@16
|
447 }
|
Chris@16
|
448 inline void eval_tanh(float128_backend& result, const float128_backend& arg)
|
Chris@16
|
449 {
|
Chris@16
|
450 result.value() = tanhq(arg.value());
|
Chris@16
|
451 }
|
Chris@16
|
452 inline void eval_fmod(float128_backend& result, const float128_backend& a, const float128_backend& b)
|
Chris@16
|
453 {
|
Chris@16
|
454 result.value() = fmodq(a.value(), b.value());
|
Chris@16
|
455 }
|
Chris@16
|
456 inline void eval_pow(float128_backend& result, const float128_backend& a, const float128_backend& b)
|
Chris@16
|
457 {
|
Chris@16
|
458 result.value() = powq(a.value(), b.value());
|
Chris@16
|
459 }
|
Chris@16
|
460 inline void eval_atan2(float128_backend& result, const float128_backend& a, const float128_backend& b)
|
Chris@16
|
461 {
|
Chris@16
|
462 result.value() = atan2q(a.value(), b.value());
|
Chris@16
|
463 }
|
Chris@16
|
464
|
Chris@16
|
465 } // namespace backends
|
Chris@16
|
466
|
Chris@16
|
467 }} // namespaces
|
Chris@16
|
468
|
Chris@16
|
469 namespace boost{
|
Chris@16
|
470 namespace archive{
|
Chris@16
|
471
|
Chris@16
|
472 class binary_oarchive;
|
Chris@16
|
473 class binary_iarchive;
|
Chris@16
|
474
|
Chris@16
|
475 }
|
Chris@16
|
476
|
Chris@16
|
477 namespace serialization{ namespace float128_detail{
|
Chris@16
|
478
|
Chris@16
|
479 template <class Archive>
|
Chris@16
|
480 void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const mpl::false_&, const mpl::false_&)
|
Chris@16
|
481 {
|
Chris@16
|
482 // saving
|
Chris@16
|
483 // non-binary
|
Chris@16
|
484 std::string s(val.str(0, std::ios_base::scientific));
|
Chris@16
|
485 ar & s;
|
Chris@16
|
486 }
|
Chris@16
|
487 template <class Archive>
|
Chris@16
|
488 void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const mpl::true_&, const mpl::false_&)
|
Chris@16
|
489 {
|
Chris@16
|
490 // loading
|
Chris@16
|
491 // non-binary
|
Chris@16
|
492 std::string s;
|
Chris@16
|
493 ar & s;
|
Chris@16
|
494 val = s.c_str();
|
Chris@16
|
495 }
|
Chris@16
|
496
|
Chris@16
|
497 template <class Archive>
|
Chris@16
|
498 void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const mpl::false_&, const mpl::true_&)
|
Chris@16
|
499 {
|
Chris@16
|
500 // saving
|
Chris@16
|
501 // binary
|
Chris@16
|
502 ar.save_binary(&val, sizeof(val));
|
Chris@16
|
503 }
|
Chris@16
|
504 template <class Archive>
|
Chris@16
|
505 void do_serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, const mpl::true_&, const mpl::true_&)
|
Chris@16
|
506 {
|
Chris@16
|
507 // loading
|
Chris@16
|
508 // binary
|
Chris@16
|
509 ar.load_binary(&val, sizeof(val));
|
Chris@16
|
510 }
|
Chris@16
|
511
|
Chris@16
|
512 } // detail
|
Chris@16
|
513
|
Chris@16
|
514 template <class Archive>
|
Chris@16
|
515 void serialize(Archive& ar, boost::multiprecision::backends::float128_backend& val, unsigned int /*version*/)
|
Chris@16
|
516 {
|
Chris@16
|
517 typedef typename Archive::is_loading load_tag;
|
Chris@16
|
518 typedef typename mpl::bool_<boost::is_same<Archive, boost::archive::binary_oarchive>::value || boost::is_same<Archive, boost::archive::binary_iarchive>::value> binary_tag;
|
Chris@16
|
519
|
Chris@16
|
520 float128_detail::do_serialize(ar, val, load_tag(), binary_tag());
|
Chris@16
|
521 }
|
Chris@16
|
522
|
Chris@16
|
523 }}
|
Chris@16
|
524
|
Chris@16
|
525 namespace std{
|
Chris@16
|
526
|
Chris@16
|
527 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@16
|
528 class numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >
|
Chris@16
|
529 {
|
Chris@16
|
530 typedef boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> number_type;
|
Chris@16
|
531 public:
|
Chris@16
|
532 BOOST_STATIC_CONSTEXPR bool is_specialized = true;
|
Chris@16
|
533 static number_type (min)() BOOST_NOEXCEPT { return 3.36210314311209350626267781732175260e-4932Q; }
|
Chris@16
|
534 static number_type (max)() BOOST_NOEXCEPT { return 1.18973149535723176508575932662800702e4932Q; }
|
Chris@16
|
535 static number_type lowest() BOOST_NOEXCEPT { return -(max)(); }
|
Chris@16
|
536 BOOST_STATIC_CONSTEXPR int digits = 113;
|
Chris@16
|
537 BOOST_STATIC_CONSTEXPR int digits10 = 34;
|
Chris@16
|
538 BOOST_STATIC_CONSTEXPR int max_digits10 = 36;
|
Chris@16
|
539 BOOST_STATIC_CONSTEXPR bool is_signed = true;
|
Chris@16
|
540 BOOST_STATIC_CONSTEXPR bool is_integer = false;
|
Chris@16
|
541 BOOST_STATIC_CONSTEXPR bool is_exact = false;
|
Chris@16
|
542 BOOST_STATIC_CONSTEXPR int radix = 2;
|
Chris@16
|
543 static number_type epsilon() { return 1.92592994438723585305597794258492732e-34Q; }
|
Chris@16
|
544 static number_type round_error() { return 0.5; }
|
Chris@16
|
545 BOOST_STATIC_CONSTEXPR int min_exponent = -16381;
|
Chris@16
|
546 BOOST_STATIC_CONSTEXPR int min_exponent10 = min_exponent * 301L / 1000L;
|
Chris@16
|
547 BOOST_STATIC_CONSTEXPR int max_exponent = 16384;
|
Chris@16
|
548 BOOST_STATIC_CONSTEXPR int max_exponent10 = max_exponent * 301L / 1000L;
|
Chris@16
|
549 BOOST_STATIC_CONSTEXPR bool has_infinity = true;
|
Chris@16
|
550 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true;
|
Chris@16
|
551 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
|
Chris@16
|
552 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
|
Chris@16
|
553 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
|
Chris@16
|
554 static number_type infinity() { return 1.0q / 0.0q; }
|
Chris@16
|
555 static number_type quiet_NaN() { return number_type("nan"); }
|
Chris@16
|
556 static number_type signaling_NaN() { return 0; }
|
Chris@16
|
557 static number_type denorm_min() { return 0; }
|
Chris@16
|
558 BOOST_STATIC_CONSTEXPR bool is_iec559 = true;
|
Chris@16
|
559 BOOST_STATIC_CONSTEXPR bool is_bounded = false;
|
Chris@16
|
560 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
|
Chris@16
|
561 BOOST_STATIC_CONSTEXPR bool traps = false;
|
Chris@16
|
562 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
|
Chris@16
|
563 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest;
|
Chris@16
|
564 };
|
Chris@16
|
565
|
Chris@101
|
566 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
567 const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_specialized;
|
Chris@101
|
568 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
569 const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits;
|
Chris@101
|
570 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
571 const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::digits10;
|
Chris@101
|
572 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
573 const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_digits10;
|
Chris@101
|
574
|
Chris@101
|
575 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
576 const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_signed;
|
Chris@101
|
577 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
578 const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_integer;
|
Chris@101
|
579 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
580 const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_exact;
|
Chris@101
|
581 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
582 const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::radix;
|
Chris@101
|
583
|
Chris@101
|
584
|
Chris@101
|
585 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
586 const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent;
|
Chris@101
|
587 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
588 const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent;
|
Chris@101
|
589 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
590 const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::min_exponent10;
|
Chris@101
|
591 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
592 const int numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::max_exponent10;
|
Chris@101
|
593
|
Chris@101
|
594 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
595 const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_infinity;
|
Chris@101
|
596 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
597 const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_quiet_NaN;
|
Chris@101
|
598 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
599 const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_signaling_NaN;
|
Chris@101
|
600 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
601 const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_denorm_loss;
|
Chris@101
|
602
|
Chris@101
|
603 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
604 const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_iec559;
|
Chris@101
|
605 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
606 const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_bounded;
|
Chris@101
|
607 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
608 const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::is_modulo;
|
Chris@101
|
609 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
610 const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::traps;
|
Chris@101
|
611 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
612 const bool numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::tinyness_before;
|
Chris@101
|
613
|
Chris@101
|
614 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
615 const float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::round_style;
|
Chris@101
|
616 template <boost::multiprecision::expression_template_option ExpressionTemplates>
|
Chris@101
|
617 const float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::backends::float128_backend, ExpressionTemplates> >::has_denorm;
|
Chris@101
|
618
|
Chris@16
|
619 } // namespace std
|
Chris@16
|
620
|
Chris@16
|
621
|
Chris@16
|
622 #endif
|