Chris@102
|
1 ///////////////////////////////////////////////////////////////////////////////
|
Chris@102
|
2 // Copyright Christopher Kormanyos 2014.
|
Chris@102
|
3 // Copyright John Maddock 2014.
|
Chris@102
|
4 // Copyright Paul Bristow 2014.
|
Chris@102
|
5 // Distributed under the Boost Software License,
|
Chris@102
|
6 // Version 1.0. (See accompanying file LICENSE_1_0.txt
|
Chris@102
|
7 // or copy at http://www.boost.org/LICENSE_1_0.txt)
|
Chris@102
|
8 //
|
Chris@102
|
9
|
Chris@102
|
10 // Implement quadruple-precision <cmath> support.
|
Chris@102
|
11
|
Chris@102
|
12 #ifndef _BOOST_CSTDFLOAT_CMATH_2014_02_15_HPP_
|
Chris@102
|
13 #define _BOOST_CSTDFLOAT_CMATH_2014_02_15_HPP_
|
Chris@102
|
14
|
Chris@102
|
15 #include <boost/math/cstdfloat/cstdfloat_types.hpp>
|
Chris@102
|
16 #include <boost/math/cstdfloat/cstdfloat_limits.hpp>
|
Chris@102
|
17
|
Chris@102
|
18 #if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT)
|
Chris@102
|
19
|
Chris@102
|
20 #include <cmath>
|
Chris@102
|
21 #include <stdexcept>
|
Chris@102
|
22 #include <boost/cstdint.hpp>
|
Chris@102
|
23 #include <boost/static_assert.hpp>
|
Chris@102
|
24 #include <boost/throw_exception.hpp>
|
Chris@102
|
25
|
Chris@102
|
26 #if defined(_WIN32) && defined(__GNUC__)
|
Chris@102
|
27 // Several versions of Mingw and probably cygwin too have broken
|
Chris@102
|
28 // libquadmath implementations that segfault as soon as you call
|
Chris@102
|
29 // expq or any function that depends on it.
|
Chris@102
|
30 #define BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS
|
Chris@102
|
31 #endif
|
Chris@102
|
32
|
Chris@102
|
33 // Here is a helper function used for raising the value of a given
|
Chris@102
|
34 // floating-point type to the power of n, where n has integral type.
|
Chris@102
|
35 namespace boost { namespace math { namespace cstdfloat { namespace detail {
|
Chris@102
|
36
|
Chris@102
|
37 template<class float_type, class integer_type>
|
Chris@102
|
38 inline float_type pown(const float_type& x, const integer_type p)
|
Chris@102
|
39 {
|
Chris@102
|
40 const bool isneg = (x < 0);
|
Chris@102
|
41 const bool isnan = (x != x);
|
Chris@102
|
42 const bool isinf = ((!isneg) ? bool(+x > (std::numeric_limits<float_type>::max)())
|
Chris@102
|
43 : bool(-x > (std::numeric_limits<float_type>::max)()));
|
Chris@102
|
44
|
Chris@102
|
45 if(isnan) { return x; }
|
Chris@102
|
46
|
Chris@102
|
47 if(isinf) { return std::numeric_limits<float_type>::quiet_NaN(); }
|
Chris@102
|
48
|
Chris@102
|
49 const bool x_is_neg = (x < 0);
|
Chris@102
|
50 const float_type abs_x = (x_is_neg ? -x : x);
|
Chris@102
|
51
|
Chris@102
|
52 if(p < static_cast<integer_type>(0))
|
Chris@102
|
53 {
|
Chris@102
|
54 if(abs_x < (std::numeric_limits<float_type>::min)())
|
Chris@102
|
55 {
|
Chris@102
|
56 return (x_is_neg ? -std::numeric_limits<float_type>::infinity()
|
Chris@102
|
57 : +std::numeric_limits<float_type>::infinity());
|
Chris@102
|
58 }
|
Chris@102
|
59 else
|
Chris@102
|
60 {
|
Chris@102
|
61 return float_type(1) / pown(x, static_cast<integer_type>(-p));
|
Chris@102
|
62 }
|
Chris@102
|
63 }
|
Chris@102
|
64
|
Chris@102
|
65 if(p == static_cast<integer_type>(0))
|
Chris@102
|
66 {
|
Chris@102
|
67 return float_type(1);
|
Chris@102
|
68 }
|
Chris@102
|
69 else
|
Chris@102
|
70 {
|
Chris@102
|
71 if(p == static_cast<integer_type>(1)) { return x; }
|
Chris@102
|
72
|
Chris@102
|
73 if(abs_x > (std::numeric_limits<float_type>::max)())
|
Chris@102
|
74 {
|
Chris@102
|
75 return (x_is_neg ? -std::numeric_limits<float_type>::infinity()
|
Chris@102
|
76 : +std::numeric_limits<float_type>::infinity());
|
Chris@102
|
77 }
|
Chris@102
|
78
|
Chris@102
|
79 if (p == static_cast<integer_type>(2)) { return (x * x); }
|
Chris@102
|
80 else if(p == static_cast<integer_type>(3)) { return ((x * x) * x); }
|
Chris@102
|
81 else if(p == static_cast<integer_type>(4)) { const float_type x2 = (x * x); return (x2 * x2); }
|
Chris@102
|
82 else
|
Chris@102
|
83 {
|
Chris@102
|
84 // The variable xn stores the binary powers of x.
|
Chris@102
|
85 float_type result(((p % integer_type(2)) != integer_type(0)) ? x : float_type(1));
|
Chris@102
|
86 float_type xn (x);
|
Chris@102
|
87
|
Chris@102
|
88 integer_type p2 = p;
|
Chris@102
|
89
|
Chris@102
|
90 while(integer_type(p2 /= 2) != integer_type(0))
|
Chris@102
|
91 {
|
Chris@102
|
92 // Square xn for each binary power.
|
Chris@102
|
93 xn *= xn;
|
Chris@102
|
94
|
Chris@102
|
95 const bool has_binary_power = (integer_type(p2 % integer_type(2)) != integer_type(0));
|
Chris@102
|
96
|
Chris@102
|
97 if(has_binary_power)
|
Chris@102
|
98 {
|
Chris@102
|
99 // Multiply the result with each binary power contained in the exponent.
|
Chris@102
|
100 result *= xn;
|
Chris@102
|
101 }
|
Chris@102
|
102 }
|
Chris@102
|
103
|
Chris@102
|
104 return result;
|
Chris@102
|
105 }
|
Chris@102
|
106 }
|
Chris@102
|
107 }
|
Chris@102
|
108
|
Chris@102
|
109 } } } } // boost::math::cstdfloat::detail
|
Chris@102
|
110
|
Chris@102
|
111 // We will now define preprocessor symbols representing quadruple-precision <cmath> functions.
|
Chris@102
|
112 #if defined(BOOST_INTEL)
|
Chris@102
|
113 #define BOOST_CSTDFLOAT_FLOAT128_LDEXP __ldexpq
|
Chris@102
|
114 #define BOOST_CSTDFLOAT_FLOAT128_FREXP __frexpq
|
Chris@102
|
115 #define BOOST_CSTDFLOAT_FLOAT128_FABS __fabsq
|
Chris@102
|
116 #define BOOST_CSTDFLOAT_FLOAT128_FLOOR __floorq
|
Chris@102
|
117 #define BOOST_CSTDFLOAT_FLOAT128_CEIL __ceilq
|
Chris@102
|
118 #if !defined(BOOST_CSTDFLOAT_FLOAT128_SQRT)
|
Chris@102
|
119 #define BOOST_CSTDFLOAT_FLOAT128_SQRT __sqrtq
|
Chris@102
|
120 #endif
|
Chris@102
|
121 #define BOOST_CSTDFLOAT_FLOAT128_TRUNC __truncq
|
Chris@102
|
122 #define BOOST_CSTDFLOAT_FLOAT128_EXP __expq
|
Chris@102
|
123 #define BOOST_CSTDFLOAT_FLOAT128_EXPM1 __expm1q
|
Chris@102
|
124 #define BOOST_CSTDFLOAT_FLOAT128_POW __powq
|
Chris@102
|
125 #define BOOST_CSTDFLOAT_FLOAT128_LOG __logq
|
Chris@102
|
126 #define BOOST_CSTDFLOAT_FLOAT128_LOG10 __log10q
|
Chris@102
|
127 #define BOOST_CSTDFLOAT_FLOAT128_SIN __sinq
|
Chris@102
|
128 #define BOOST_CSTDFLOAT_FLOAT128_COS __cosq
|
Chris@102
|
129 #define BOOST_CSTDFLOAT_FLOAT128_TAN __tanq
|
Chris@102
|
130 #define BOOST_CSTDFLOAT_FLOAT128_ASIN __asinq
|
Chris@102
|
131 #define BOOST_CSTDFLOAT_FLOAT128_ACOS __acosq
|
Chris@102
|
132 #define BOOST_CSTDFLOAT_FLOAT128_ATAN __atanq
|
Chris@102
|
133 #define BOOST_CSTDFLOAT_FLOAT128_SINH __sinhq
|
Chris@102
|
134 #define BOOST_CSTDFLOAT_FLOAT128_COSH __coshq
|
Chris@102
|
135 #define BOOST_CSTDFLOAT_FLOAT128_TANH __tanhq
|
Chris@102
|
136 #define BOOST_CSTDFLOAT_FLOAT128_ASINH __asinhq
|
Chris@102
|
137 #define BOOST_CSTDFLOAT_FLOAT128_ACOSH __acoshq
|
Chris@102
|
138 #define BOOST_CSTDFLOAT_FLOAT128_ATANH __atanhq
|
Chris@102
|
139 #define BOOST_CSTDFLOAT_FLOAT128_FMOD __fmodq
|
Chris@102
|
140 #define BOOST_CSTDFLOAT_FLOAT128_ATAN2 __atan2q
|
Chris@102
|
141 #define BOOST_CSTDFLOAT_FLOAT128_LGAMMA __lgammaq
|
Chris@102
|
142 #define BOOST_CSTDFLOAT_FLOAT128_TGAMMA __tgammaq
|
Chris@102
|
143 #elif defined(__GNUC__)
|
Chris@102
|
144 #define BOOST_CSTDFLOAT_FLOAT128_LDEXP ldexpq
|
Chris@102
|
145 #define BOOST_CSTDFLOAT_FLOAT128_FREXP frexpq
|
Chris@102
|
146 #define BOOST_CSTDFLOAT_FLOAT128_FABS fabsq
|
Chris@102
|
147 #define BOOST_CSTDFLOAT_FLOAT128_FLOOR floorq
|
Chris@102
|
148 #define BOOST_CSTDFLOAT_FLOAT128_CEIL ceilq
|
Chris@102
|
149 #if !defined(BOOST_CSTDFLOAT_FLOAT128_SQRT)
|
Chris@102
|
150 #define BOOST_CSTDFLOAT_FLOAT128_SQRT sqrtq
|
Chris@102
|
151 #endif
|
Chris@102
|
152 #define BOOST_CSTDFLOAT_FLOAT128_TRUNC truncq
|
Chris@102
|
153 #define BOOST_CSTDFLOAT_FLOAT128_POW powq
|
Chris@102
|
154 #define BOOST_CSTDFLOAT_FLOAT128_LOG logq
|
Chris@102
|
155 #define BOOST_CSTDFLOAT_FLOAT128_LOG10 log10q
|
Chris@102
|
156 #define BOOST_CSTDFLOAT_FLOAT128_SIN sinq
|
Chris@102
|
157 #define BOOST_CSTDFLOAT_FLOAT128_COS cosq
|
Chris@102
|
158 #define BOOST_CSTDFLOAT_FLOAT128_TAN tanq
|
Chris@102
|
159 #define BOOST_CSTDFLOAT_FLOAT128_ASIN asinq
|
Chris@102
|
160 #define BOOST_CSTDFLOAT_FLOAT128_ACOS acosq
|
Chris@102
|
161 #define BOOST_CSTDFLOAT_FLOAT128_ATAN atanq
|
Chris@102
|
162 #define BOOST_CSTDFLOAT_FLOAT128_FMOD fmodq
|
Chris@102
|
163 #define BOOST_CSTDFLOAT_FLOAT128_ATAN2 atan2q
|
Chris@102
|
164 #define BOOST_CSTDFLOAT_FLOAT128_LGAMMA lgammaq
|
Chris@102
|
165 #if !defined(BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS)
|
Chris@102
|
166 #define BOOST_CSTDFLOAT_FLOAT128_EXP expq
|
Chris@102
|
167 #define BOOST_CSTDFLOAT_FLOAT128_EXPM1 expm1q_internal
|
Chris@102
|
168 #define BOOST_CSTDFLOAT_FLOAT128_SINH sinhq
|
Chris@102
|
169 #define BOOST_CSTDFLOAT_FLOAT128_COSH coshq
|
Chris@102
|
170 #define BOOST_CSTDFLOAT_FLOAT128_TANH tanhq
|
Chris@102
|
171 #define BOOST_CSTDFLOAT_FLOAT128_ASINH asinhq
|
Chris@102
|
172 #define BOOST_CSTDFLOAT_FLOAT128_ACOSH acoshq
|
Chris@102
|
173 #define BOOST_CSTDFLOAT_FLOAT128_ATANH atanhq
|
Chris@102
|
174 #define BOOST_CSTDFLOAT_FLOAT128_TGAMMA tgammaq
|
Chris@102
|
175 #else // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS
|
Chris@102
|
176 #define BOOST_CSTDFLOAT_FLOAT128_EXP expq_patch
|
Chris@102
|
177 #define BOOST_CSTDFLOAT_FLOAT128_SINH sinhq_patch
|
Chris@102
|
178 #define BOOST_CSTDFLOAT_FLOAT128_COSH coshq_patch
|
Chris@102
|
179 #define BOOST_CSTDFLOAT_FLOAT128_TANH tanhq_patch
|
Chris@102
|
180 #define BOOST_CSTDFLOAT_FLOAT128_ASINH asinhq_patch
|
Chris@102
|
181 #define BOOST_CSTDFLOAT_FLOAT128_ACOSH acoshq_patch
|
Chris@102
|
182 #define BOOST_CSTDFLOAT_FLOAT128_ATANH atanhq_patch
|
Chris@102
|
183 #define BOOST_CSTDFLOAT_FLOAT128_TGAMMA tgammaq_patch
|
Chris@102
|
184 #endif // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS
|
Chris@102
|
185 #endif
|
Chris@102
|
186
|
Chris@102
|
187 // Implement quadruple-precision <cmath> functions in the namespace
|
Chris@102
|
188 // boost::math::cstdfloat::detail. Subsequently inject these into the
|
Chris@102
|
189 // std namespace via *using* directive.
|
Chris@102
|
190
|
Chris@102
|
191 // Begin with some forward function declarations. Also implement patches
|
Chris@102
|
192 // for compilers that have broken float128 exponential functions.
|
Chris@102
|
193
|
Chris@102
|
194 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LDEXP (boost::math::cstdfloat::detail::float_internal128_t, int) throw();
|
Chris@102
|
195 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FREXP (boost::math::cstdfloat::detail::float_internal128_t, int*) throw();
|
Chris@102
|
196 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FABS (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
Chris@102
|
197 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FLOOR (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
Chris@102
|
198 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_CEIL (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
Chris@102
|
199 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SQRT (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
Chris@102
|
200 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TRUNC (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
Chris@102
|
201 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_POW (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw();
|
Chris@102
|
202 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOG (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
Chris@102
|
203 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOG10 (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
Chris@102
|
204 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SIN (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
Chris@102
|
205 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COS (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
Chris@102
|
206 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TAN (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
Chris@102
|
207 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ASIN (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
Chris@102
|
208 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ACOS (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
Chris@102
|
209 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATAN (boost::math::cstdfloat::detail::float_internal128_t) throw();
|
Chris@102
|
210 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FMOD (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw();
|
Chris@102
|
211 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATAN2 (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw();
|
Chris@102
|
212 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LGAMMA(boost::math::cstdfloat::detail::float_internal128_t) throw();
|
Chris@102
|
213
|
Chris@102
|
214 #if !defined(BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS)
|
Chris@102
|
215
|
Chris@102
|
216 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP (boost::math::cstdfloat::detail::float_internal128_t x) throw();
|
Chris@102
|
217 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SINH (boost::math::cstdfloat::detail::float_internal128_t x) throw();
|
Chris@102
|
218 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COSH (boost::math::cstdfloat::detail::float_internal128_t x) throw();
|
Chris@102
|
219 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TANH (boost::math::cstdfloat::detail::float_internal128_t x) throw();
|
Chris@102
|
220 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ASINH (boost::math::cstdfloat::detail::float_internal128_t x) throw();
|
Chris@102
|
221 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ACOSH (boost::math::cstdfloat::detail::float_internal128_t x) throw();
|
Chris@102
|
222 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATANH (boost::math::cstdfloat::detail::float_internal128_t x) throw();
|
Chris@102
|
223 extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TGAMMA(boost::math::cstdfloat::detail::float_internal128_t x) throw();
|
Chris@102
|
224
|
Chris@102
|
225 #else // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS
|
Chris@102
|
226
|
Chris@102
|
227 // Forward declaration of the patched exponent function, exp(x).
|
Chris@102
|
228 inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP (boost::math::cstdfloat::detail::float_internal128_t x);
|
Chris@102
|
229
|
Chris@102
|
230 inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXPM1 (boost::math::cstdfloat::detail::float_internal128_t x)
|
Chris@102
|
231 {
|
Chris@102
|
232 // Compute exp(x) - 1 for x small.
|
Chris@102
|
233
|
Chris@102
|
234 // Use an order-36 polynomial approximation of the exponential function
|
Chris@102
|
235 // in the range of (-ln2 < x < ln2). Scale the argument to this range
|
Chris@102
|
236 // and subsequently multiply the result by 2^n accordingly.
|
Chris@102
|
237
|
Chris@102
|
238 // Derive the polynomial coefficients with Mathematica(R) by generating
|
Chris@102
|
239 // a table of high-precision values of exp(x) in the range (-ln2 < x < ln2)
|
Chris@102
|
240 // and subsequently applying the built-in *Fit* function.
|
Chris@102
|
241
|
Chris@102
|
242 // Table[{x, Exp[x] - 1}, {x, -Log[2], Log[2], 1/180}]
|
Chris@102
|
243 // N[%, 120]
|
Chris@102
|
244 // Fit[%, {x, x^2, x^3, x^4, x^5, x^6, x^7, x^8, x^9, x^10, x^11, x^12,
|
Chris@102
|
245 // x^13, x^14, x^15, x^16, x^17, x^18, x^19, x^20, x^21, x^22,
|
Chris@102
|
246 // x^23, x^24, x^25, x^26, x^27, x^28, x^29, x^30, x^31, x^32,
|
Chris@102
|
247 // x^33, x^34, x^35, x^36}, x]
|
Chris@102
|
248
|
Chris@102
|
249 typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
|
Chris@102
|
250
|
Chris@102
|
251 float_type sum;
|
Chris@102
|
252
|
Chris@102
|
253 if(x > BOOST_FLOAT128_C(0.693147180559945309417232121458176568075500134360255))
|
Chris@102
|
254 {
|
Chris@102
|
255 sum = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x) - float_type(1);
|
Chris@102
|
256 }
|
Chris@102
|
257 else
|
Chris@102
|
258 {
|
Chris@102
|
259 // Compute the polynomial approximation of exp(alpha).
|
Chris@102
|
260 sum = (((((((((((((((((((((((((((((((((((( float_type(BOOST_FLOAT128_C(2.69291698127774166063293705964720493864630783729857438187365E-42)) * x
|
Chris@102
|
261 + float_type(BOOST_FLOAT128_C(9.70937085471487654794114679403710456028986572118859594614033E-41))) * x
|
Chris@102
|
262 + float_type(BOOST_FLOAT128_C(3.38715585158055097155585505318085512156885389014410753080500E-39))) * x
|
Chris@102
|
263 + float_type(BOOST_FLOAT128_C(1.15162718532861050809222658798662695267019717760563645440433E-37))) * x
|
Chris@102
|
264 + float_type(BOOST_FLOAT128_C(3.80039074689434663295873584133017767349635602413675471702393E-36))) * x
|
Chris@102
|
265 + float_type(BOOST_FLOAT128_C(1.21612504934087520075905434734158045947460467096773246215239E-34))) * x
|
Chris@102
|
266 + float_type(BOOST_FLOAT128_C(3.76998762883139753126119821241037824830069851253295480396224E-33))) * x
|
Chris@102
|
267 + float_type(BOOST_FLOAT128_C(1.13099628863830344684998293828608215735777107850991029729440E-31))) * x
|
Chris@102
|
268 + float_type(BOOST_FLOAT128_C(3.27988923706982293204067897468714277771890104022419696770352E-30))) * x
|
Chris@102
|
269 + float_type(BOOST_FLOAT128_C(9.18368986379558482800593745627556950089950023355628325088207E-29))) * x
|
Chris@102
|
270 + float_type(BOOST_FLOAT128_C(2.47959626322479746949155352659617642905315302382639380521497E-27))) * x
|
Chris@102
|
271 + float_type(BOOST_FLOAT128_C(6.44695028438447337900255966737803112935639344283098705091949E-26))) * x
|
Chris@102
|
272 + float_type(BOOST_FLOAT128_C(1.61173757109611834904452725462599961406036904573072897122957E-24))) * x
|
Chris@102
|
273 + float_type(BOOST_FLOAT128_C(3.86817017063068403772269360016918092488847584660382953555804E-23))) * x
|
Chris@102
|
274 + float_type(BOOST_FLOAT128_C(8.89679139245057328674891109315654704307721758924206107351744E-22))) * x
|
Chris@102
|
275 + float_type(BOOST_FLOAT128_C(1.95729410633912612308475595397946731738088422488032228717097E-20))) * x
|
Chris@102
|
276 + float_type(BOOST_FLOAT128_C(4.11031762331216485847799061511674191805055663711439605760231E-19))) * x
|
Chris@102
|
277 + float_type(BOOST_FLOAT128_C(8.22063524662432971695598123977873600603370758794431071426640E-18))) * x
|
Chris@102
|
278 + float_type(BOOST_FLOAT128_C(1.56192069685862264622163643500633782667263448653185159383285E-16))) * x
|
Chris@102
|
279 + float_type(BOOST_FLOAT128_C(2.81145725434552076319894558300988749849555291507956994126835E-15))) * x
|
Chris@102
|
280 + float_type(BOOST_FLOAT128_C(4.77947733238738529743820749111754320727153728139716409114011E-14))) * x
|
Chris@102
|
281 + float_type(BOOST_FLOAT128_C(7.64716373181981647590113198578807092707697416852226691068627E-13))) * x
|
Chris@102
|
282 + float_type(BOOST_FLOAT128_C(1.14707455977297247138516979786821056670509688396295740818677E-11))) * x
|
Chris@102
|
283 + float_type(BOOST_FLOAT128_C(1.60590438368216145993923771701549479323291461578567184216302E-10))) * x
|
Chris@102
|
284 + float_type(BOOST_FLOAT128_C(2.08767569878680989792100903212014323125428376052986408239620E-09))) * x
|
Chris@102
|
285 + float_type(BOOST_FLOAT128_C(2.50521083854417187750521083854417187750523408006206780016659E-08))) * x
|
Chris@102
|
286 + float_type(BOOST_FLOAT128_C(2.75573192239858906525573192239858906525573195144226062684604E-07))) * x
|
Chris@102
|
287 + float_type(BOOST_FLOAT128_C(2.75573192239858906525573192239858906525573191310049321957902E-06))) * x
|
Chris@102
|
288 + float_type(BOOST_FLOAT128_C(0.00002480158730158730158730158730158730158730158730149317774))) * x
|
Chris@102
|
289 + float_type(BOOST_FLOAT128_C(0.00019841269841269841269841269841269841269841269841293575920))) * x
|
Chris@102
|
290 + float_type(BOOST_FLOAT128_C(0.00138888888888888888888888888888888888888888888888889071045))) * x
|
Chris@102
|
291 + float_type(BOOST_FLOAT128_C(0.00833333333333333333333333333333333333333333333333332986595))) * x
|
Chris@102
|
292 + float_type(BOOST_FLOAT128_C(0.04166666666666666666666666666666666666666666666666666664876))) * x
|
Chris@102
|
293 + float_type(BOOST_FLOAT128_C(0.16666666666666666666666666666666666666666666666666666669048))) * x
|
Chris@102
|
294 + float_type(BOOST_FLOAT128_C(0.50000000000000000000000000000000000000000000000000000000006))) * x
|
Chris@102
|
295 + float_type(BOOST_FLOAT128_C(0.99999999999999999999999999999999999999999999999999999999995))) * x);
|
Chris@102
|
296 }
|
Chris@102
|
297
|
Chris@102
|
298 return sum;
|
Chris@102
|
299 }
|
Chris@102
|
300 inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP (boost::math::cstdfloat::detail::float_internal128_t x)
|
Chris@102
|
301 {
|
Chris@102
|
302 // Patch the expq() function for a subset of broken GCC compilers
|
Chris@102
|
303 // like GCC 4.7, 4.8 on MinGW.
|
Chris@102
|
304
|
Chris@102
|
305 // Use an order-36 polynomial approximation of the exponential function
|
Chris@102
|
306 // in the range of (-ln2 < x < ln2). Scale the argument to this range
|
Chris@102
|
307 // and subsequently multiply the result by 2^n accordingly.
|
Chris@102
|
308
|
Chris@102
|
309 // Derive the polynomial coefficients with Mathematica(R) by generating
|
Chris@102
|
310 // a table of high-precision values of exp(x) in the range (-ln2 < x < ln2)
|
Chris@102
|
311 // and subsequently applying the built-in *Fit* function.
|
Chris@102
|
312
|
Chris@102
|
313 // Table[{x, Exp[x] - 1}, {x, -Log[2], Log[2], 1/180}]
|
Chris@102
|
314 // N[%, 120]
|
Chris@102
|
315 // Fit[%, {x, x^2, x^3, x^4, x^5, x^6, x^7, x^8, x^9, x^10, x^11, x^12,
|
Chris@102
|
316 // x^13, x^14, x^15, x^16, x^17, x^18, x^19, x^20, x^21, x^22,
|
Chris@102
|
317 // x^23, x^24, x^25, x^26, x^27, x^28, x^29, x^30, x^31, x^32,
|
Chris@102
|
318 // x^33, x^34, x^35, x^36}, x]
|
Chris@102
|
319
|
Chris@102
|
320 typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
|
Chris@102
|
321
|
Chris@102
|
322 // Scale the argument x to the range (-ln2 < x < ln2).
|
Chris@102
|
323 BOOST_CONSTEXPR_OR_CONST float_type one_over_ln2 = float_type(BOOST_FLOAT128_C(1.44269504088896340735992468100189213742664595415299));
|
Chris@102
|
324 const float_type x_over_ln2 = x * one_over_ln2;
|
Chris@102
|
325
|
Chris@102
|
326 boost::int_fast32_t n;
|
Chris@102
|
327
|
Chris@102
|
328 if(x != x)
|
Chris@102
|
329 {
|
Chris@102
|
330 // The argument is NaN.
|
Chris@102
|
331 return std::numeric_limits<float_type>::quiet_NaN();
|
Chris@102
|
332 }
|
Chris@102
|
333 else if(::BOOST_CSTDFLOAT_FLOAT128_FABS(x) > BOOST_FLOAT128_C(+0.693147180559945309417232121458176568075500134360255))
|
Chris@102
|
334 {
|
Chris@102
|
335 // The absolute value of the argument exceeds ln2.
|
Chris@102
|
336 n = static_cast<boost::int_fast32_t>(::BOOST_CSTDFLOAT_FLOAT128_FLOOR(x_over_ln2));
|
Chris@102
|
337 }
|
Chris@102
|
338 else if(::BOOST_CSTDFLOAT_FLOAT128_FABS(x) < BOOST_FLOAT128_C(+0.693147180559945309417232121458176568075500134360255))
|
Chris@102
|
339 {
|
Chris@102
|
340 // The absolute value of the argument is less than ln2.
|
Chris@102
|
341 n = static_cast<boost::int_fast32_t>(0);
|
Chris@102
|
342 }
|
Chris@102
|
343 else
|
Chris@102
|
344 {
|
Chris@102
|
345 // The absolute value of the argument is exactly equal to ln2 (in the sense of floating-point equality).
|
Chris@102
|
346 return float_type(2);
|
Chris@102
|
347 }
|
Chris@102
|
348
|
Chris@102
|
349 // Check if the argument is very near an integer.
|
Chris@102
|
350 const float_type floor_of_x = ::BOOST_CSTDFLOAT_FLOAT128_FLOOR(x);
|
Chris@102
|
351
|
Chris@102
|
352 if(::BOOST_CSTDFLOAT_FLOAT128_FABS(x - floor_of_x) < float_type(BOOST_CSTDFLOAT_FLOAT128_EPS))
|
Chris@102
|
353 {
|
Chris@102
|
354 // Return e^n for arguments very near an integer.
|
Chris@102
|
355 return boost::math::cstdfloat::detail::pown(BOOST_FLOAT128_C(2.71828182845904523536028747135266249775724709369996), static_cast<boost::int_fast32_t>(floor_of_x));
|
Chris@102
|
356 }
|
Chris@102
|
357
|
Chris@102
|
358 // Compute the scaled argument alpha.
|
Chris@102
|
359 const float_type alpha = x - (n * BOOST_FLOAT128_C(0.693147180559945309417232121458176568075500134360255));
|
Chris@102
|
360
|
Chris@102
|
361 // Compute the polynomial approximation of expm1(alpha) and add to it
|
Chris@102
|
362 // in order to obtain the scaled result.
|
Chris@102
|
363 const float_type scaled_result = ::BOOST_CSTDFLOAT_FLOAT128_EXPM1(alpha) + float_type(1);
|
Chris@102
|
364
|
Chris@102
|
365 // Rescale the result and return it.
|
Chris@102
|
366 return scaled_result * boost::math::cstdfloat::detail::pown(float_type(2), n);
|
Chris@102
|
367 }
|
Chris@102
|
368 inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SINH (boost::math::cstdfloat::detail::float_internal128_t x)
|
Chris@102
|
369 {
|
Chris@102
|
370 // Patch the sinhq() function for a subset of broken GCC compilers
|
Chris@102
|
371 // like GCC 4.7, 4.8 on MinGW.
|
Chris@102
|
372 typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
|
Chris@102
|
373
|
Chris@102
|
374 // Here, we use the following:
|
Chris@102
|
375 // Set: ex = exp(x)
|
Chris@102
|
376 // Set: em1 = expm1(x)
|
Chris@102
|
377 // Then
|
Chris@102
|
378 // sinh(x) = (ex - 1/ex) / 2 ; for |x| >= 1
|
Chris@102
|
379 // sinh(x) = (2em1 + em1^2) / (2ex) ; for |x| < 1
|
Chris@102
|
380
|
Chris@102
|
381 const float_type ex = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x);
|
Chris@102
|
382
|
Chris@102
|
383 if(::BOOST_CSTDFLOAT_FLOAT128_FABS(x) < float_type(+1))
|
Chris@102
|
384 {
|
Chris@102
|
385 const float_type em1 = ::BOOST_CSTDFLOAT_FLOAT128_EXPM1(x);
|
Chris@102
|
386
|
Chris@102
|
387 return ((em1 * 2) + (em1 * em1)) / (ex * 2);
|
Chris@102
|
388 }
|
Chris@102
|
389 else
|
Chris@102
|
390 {
|
Chris@102
|
391 return (ex - (float_type(1) / ex)) / 2;
|
Chris@102
|
392 }
|
Chris@102
|
393 }
|
Chris@102
|
394 inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COSH (boost::math::cstdfloat::detail::float_internal128_t x)
|
Chris@102
|
395 {
|
Chris@102
|
396 // Patch the coshq() function for a subset of broken GCC compilers
|
Chris@102
|
397 // like GCC 4.7, 4.8 on MinGW.
|
Chris@102
|
398 typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
|
Chris@102
|
399 const float_type ex = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x);
|
Chris@102
|
400 return (ex + (float_type(1) / ex)) / 2;
|
Chris@102
|
401 }
|
Chris@102
|
402 inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TANH (boost::math::cstdfloat::detail::float_internal128_t x)
|
Chris@102
|
403 {
|
Chris@102
|
404 // Patch the tanhq() function for a subset of broken GCC compilers
|
Chris@102
|
405 // like GCC 4.7, 4.8 on MinGW.
|
Chris@102
|
406 typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
|
Chris@102
|
407 const float_type ex_plus = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x);
|
Chris@102
|
408 const float_type ex_minus = (float_type(1) / ex_plus);
|
Chris@102
|
409 return (ex_plus - ex_minus) / (ex_plus + ex_minus);
|
Chris@102
|
410 }
|
Chris@102
|
411 inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ASINH(boost::math::cstdfloat::detail::float_internal128_t x) throw()
|
Chris@102
|
412 {
|
Chris@102
|
413 // Patch the asinh() function since quadmath does not have it.
|
Chris@102
|
414 typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
|
Chris@102
|
415 return ::BOOST_CSTDFLOAT_FLOAT128_LOG(x + ::BOOST_CSTDFLOAT_FLOAT128_SQRT((x * x) + float_type(1)));
|
Chris@102
|
416 }
|
Chris@102
|
417 inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ACOSH(boost::math::cstdfloat::detail::float_internal128_t x) throw()
|
Chris@102
|
418 {
|
Chris@102
|
419 // Patch the acosh() function since quadmath does not have it.
|
Chris@102
|
420 typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
|
Chris@102
|
421 const float_type zp(x + float_type(1));
|
Chris@102
|
422 const float_type zm(x - float_type(1));
|
Chris@102
|
423
|
Chris@102
|
424 return ::BOOST_CSTDFLOAT_FLOAT128_LOG(x + (zp * ::BOOST_CSTDFLOAT_FLOAT128_SQRT(zm / zp)));
|
Chris@102
|
425 }
|
Chris@102
|
426 inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATANH(boost::math::cstdfloat::detail::float_internal128_t x) throw()
|
Chris@102
|
427 {
|
Chris@102
|
428 // Patch the atanh() function since quadmath does not have it.
|
Chris@102
|
429 typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
|
Chris@102
|
430 return ( ::BOOST_CSTDFLOAT_FLOAT128_LOG(float_type(1) + x)
|
Chris@102
|
431 - ::BOOST_CSTDFLOAT_FLOAT128_LOG(float_type(1) - x)) / 2;
|
Chris@102
|
432 }
|
Chris@102
|
433 inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TGAMMA(boost::math::cstdfloat::detail::float_internal128_t x) throw()
|
Chris@102
|
434 {
|
Chris@102
|
435 // Patch the tgammaq() function for a subset of broken GCC compilers
|
Chris@102
|
436 // like GCC 4.7, 4.8 on MinGW.
|
Chris@102
|
437 typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
|
Chris@102
|
438
|
Chris@102
|
439 if(x > float_type(0))
|
Chris@102
|
440 {
|
Chris@102
|
441 return ::BOOST_CSTDFLOAT_FLOAT128_EXP(::BOOST_CSTDFLOAT_FLOAT128_LGAMMA(x));
|
Chris@102
|
442 }
|
Chris@102
|
443 else if(x < float_type(0))
|
Chris@102
|
444 {
|
Chris@102
|
445 // For x < 0, compute tgamma(-x) and use the reflection formula.
|
Chris@102
|
446 const float_type positive_x = -x;
|
Chris@102
|
447 float_type gamma_value = ::BOOST_CSTDFLOAT_FLOAT128_TGAMMA(positive_x);
|
Chris@102
|
448 const float_type floor_of_positive_x = ::BOOST_CSTDFLOAT_FLOAT128_FLOOR (positive_x);
|
Chris@102
|
449
|
Chris@102
|
450 // Take the reflection checks (slightly adapted) from <boost/math/gamma.hpp>.
|
Chris@102
|
451 const bool floor_of_z_is_equal_to_z = (positive_x == ::BOOST_CSTDFLOAT_FLOAT128_FLOOR(positive_x));
|
Chris@102
|
452
|
Chris@102
|
453 BOOST_CONSTEXPR_OR_CONST float_type my_pi = BOOST_FLOAT128_C(3.14159265358979323846264338327950288419716939937511);
|
Chris@102
|
454
|
Chris@102
|
455 if(floor_of_z_is_equal_to_z)
|
Chris@102
|
456 {
|
Chris@102
|
457 const bool is_odd = ((boost::int32_t(floor_of_positive_x) % boost::int32_t(2)) != boost::int32_t(0));
|
Chris@102
|
458
|
Chris@102
|
459 return (is_odd ? -std::numeric_limits<float_type>::infinity()
|
Chris@102
|
460 : +std::numeric_limits<float_type>::infinity());
|
Chris@102
|
461 }
|
Chris@102
|
462
|
Chris@102
|
463 const float_type sinpx_value = x * ::BOOST_CSTDFLOAT_FLOAT128_SIN(my_pi * x);
|
Chris@102
|
464
|
Chris@102
|
465 gamma_value *= sinpx_value;
|
Chris@102
|
466
|
Chris@102
|
467 const bool result_is_too_large_to_represent = ( (::BOOST_CSTDFLOAT_FLOAT128_FABS(gamma_value) < float_type(1))
|
Chris@102
|
468 && (((std::numeric_limits<float_type>::max)() * ::BOOST_CSTDFLOAT_FLOAT128_FABS(gamma_value)) < my_pi));
|
Chris@102
|
469
|
Chris@102
|
470 if(result_is_too_large_to_represent)
|
Chris@102
|
471 {
|
Chris@102
|
472 const bool is_odd = ((boost::int32_t(floor_of_positive_x) % boost::int32_t(2)) != boost::int32_t(0));
|
Chris@102
|
473
|
Chris@102
|
474 return (is_odd ? -std::numeric_limits<float_type>::infinity()
|
Chris@102
|
475 : +std::numeric_limits<float_type>::infinity());
|
Chris@102
|
476 }
|
Chris@102
|
477
|
Chris@102
|
478 gamma_value = -my_pi / gamma_value;
|
Chris@102
|
479
|
Chris@102
|
480 if((gamma_value > float_type(0)) || (gamma_value < float_type(0)))
|
Chris@102
|
481 {
|
Chris@102
|
482 return gamma_value;
|
Chris@102
|
483 }
|
Chris@102
|
484 else
|
Chris@102
|
485 {
|
Chris@102
|
486 // The value of gamma is too small to represent. Return 0.0 here.
|
Chris@102
|
487 return float_type(0);
|
Chris@102
|
488 }
|
Chris@102
|
489 }
|
Chris@102
|
490 else
|
Chris@102
|
491 {
|
Chris@102
|
492 // Gamma of zero is complex infinity. Return NaN here.
|
Chris@102
|
493 return std::numeric_limits<float_type>::quiet_NaN();
|
Chris@102
|
494 }
|
Chris@102
|
495 }
|
Chris@102
|
496 #endif // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS
|
Chris@102
|
497
|
Chris@102
|
498 // Define the quadruple-precision <cmath> functions in the namespace boost::math::cstdfloat::detail.
|
Chris@102
|
499
|
Chris@102
|
500 namespace boost { namespace math { namespace cstdfloat { namespace detail {
|
Chris@102
|
501 inline boost::math::cstdfloat::detail::float_internal128_t ldexp (boost::math::cstdfloat::detail::float_internal128_t x, int n) { return ::BOOST_CSTDFLOAT_FLOAT128_LDEXP (x, n); }
|
Chris@102
|
502 inline boost::math::cstdfloat::detail::float_internal128_t frexp (boost::math::cstdfloat::detail::float_internal128_t x, int* pn) { return ::BOOST_CSTDFLOAT_FLOAT128_FREXP (x, pn); }
|
Chris@102
|
503 inline boost::math::cstdfloat::detail::float_internal128_t fabs (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_FABS (x); }
|
Chris@102
|
504 inline boost::math::cstdfloat::detail::float_internal128_t abs (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_FABS (x); }
|
Chris@102
|
505 inline boost::math::cstdfloat::detail::float_internal128_t floor (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_FLOOR (x); }
|
Chris@102
|
506 inline boost::math::cstdfloat::detail::float_internal128_t ceil (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_CEIL (x); }
|
Chris@102
|
507 inline boost::math::cstdfloat::detail::float_internal128_t sqrt (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SQRT (x); }
|
Chris@102
|
508 inline boost::math::cstdfloat::detail::float_internal128_t trunc (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TRUNC (x); }
|
Chris@102
|
509 inline boost::math::cstdfloat::detail::float_internal128_t exp (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_EXP (x); }
|
Chris@102
|
510 inline boost::math::cstdfloat::detail::float_internal128_t pow (boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t a) { return ::BOOST_CSTDFLOAT_FLOAT128_POW (x, a); }
|
Chris@102
|
511 inline boost::math::cstdfloat::detail::float_internal128_t pow (boost::math::cstdfloat::detail::float_internal128_t x, int a) { return ::BOOST_CSTDFLOAT_FLOAT128_POW (x, boost::math::cstdfloat::detail::float_internal128_t(a)); }
|
Chris@102
|
512 inline boost::math::cstdfloat::detail::float_internal128_t log (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOG (x); }
|
Chris@102
|
513 inline boost::math::cstdfloat::detail::float_internal128_t log10 (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOG10 (x); }
|
Chris@102
|
514 inline boost::math::cstdfloat::detail::float_internal128_t sin (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SIN (x); }
|
Chris@102
|
515 inline boost::math::cstdfloat::detail::float_internal128_t cos (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_COS (x); }
|
Chris@102
|
516 inline boost::math::cstdfloat::detail::float_internal128_t tan (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TAN (x); }
|
Chris@102
|
517 inline boost::math::cstdfloat::detail::float_internal128_t asin (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ASIN (x); }
|
Chris@102
|
518 inline boost::math::cstdfloat::detail::float_internal128_t acos (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ACOS (x); }
|
Chris@102
|
519 inline boost::math::cstdfloat::detail::float_internal128_t atan (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ATAN (x); }
|
Chris@102
|
520 inline boost::math::cstdfloat::detail::float_internal128_t sinh (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SINH (x); }
|
Chris@102
|
521 inline boost::math::cstdfloat::detail::float_internal128_t cosh (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_COSH (x); }
|
Chris@102
|
522 inline boost::math::cstdfloat::detail::float_internal128_t tanh (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TANH (x); }
|
Chris@102
|
523 inline boost::math::cstdfloat::detail::float_internal128_t asinh (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ASINH (x); }
|
Chris@102
|
524 inline boost::math::cstdfloat::detail::float_internal128_t acosh (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ACOSH (x); }
|
Chris@102
|
525 inline boost::math::cstdfloat::detail::float_internal128_t atanh (boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ATANH (x); }
|
Chris@102
|
526 inline boost::math::cstdfloat::detail::float_internal128_t fmod (boost::math::cstdfloat::detail::float_internal128_t a, boost::math::cstdfloat::detail::float_internal128_t b) { return ::BOOST_CSTDFLOAT_FLOAT128_FMOD (a, b); }
|
Chris@102
|
527 inline boost::math::cstdfloat::detail::float_internal128_t atan2 (boost::math::cstdfloat::detail::float_internal128_t y, boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ATAN2 (y, x); }
|
Chris@102
|
528 inline boost::math::cstdfloat::detail::float_internal128_t lgamma(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LGAMMA(x); }
|
Chris@102
|
529 inline boost::math::cstdfloat::detail::float_internal128_t tgamma(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TGAMMA(x); }
|
Chris@102
|
530 } } } } // boost::math::cstdfloat::detail
|
Chris@102
|
531
|
Chris@102
|
532 // We will now inject the quadruple-precision <cmath> functions
|
Chris@102
|
533 // into the std namespace. This is done via *using* directive.
|
Chris@102
|
534 namespace std
|
Chris@102
|
535 {
|
Chris@102
|
536 using boost::math::cstdfloat::detail::ldexp;
|
Chris@102
|
537 using boost::math::cstdfloat::detail::frexp;
|
Chris@102
|
538 using boost::math::cstdfloat::detail::fabs;
|
Chris@102
|
539 using boost::math::cstdfloat::detail::abs;
|
Chris@102
|
540 using boost::math::cstdfloat::detail::floor;
|
Chris@102
|
541 using boost::math::cstdfloat::detail::ceil;
|
Chris@102
|
542 using boost::math::cstdfloat::detail::sqrt;
|
Chris@102
|
543 using boost::math::cstdfloat::detail::trunc;
|
Chris@102
|
544 using boost::math::cstdfloat::detail::exp;
|
Chris@102
|
545 using boost::math::cstdfloat::detail::pow;
|
Chris@102
|
546 using boost::math::cstdfloat::detail::log;
|
Chris@102
|
547 using boost::math::cstdfloat::detail::log10;
|
Chris@102
|
548 using boost::math::cstdfloat::detail::sin;
|
Chris@102
|
549 using boost::math::cstdfloat::detail::cos;
|
Chris@102
|
550 using boost::math::cstdfloat::detail::tan;
|
Chris@102
|
551 using boost::math::cstdfloat::detail::asin;
|
Chris@102
|
552 using boost::math::cstdfloat::detail::acos;
|
Chris@102
|
553 using boost::math::cstdfloat::detail::atan;
|
Chris@102
|
554 using boost::math::cstdfloat::detail::sinh;
|
Chris@102
|
555 using boost::math::cstdfloat::detail::cosh;
|
Chris@102
|
556 using boost::math::cstdfloat::detail::tanh;
|
Chris@102
|
557 using boost::math::cstdfloat::detail::asinh;
|
Chris@102
|
558 using boost::math::cstdfloat::detail::acosh;
|
Chris@102
|
559 using boost::math::cstdfloat::detail::atanh;
|
Chris@102
|
560 using boost::math::cstdfloat::detail::fmod;
|
Chris@102
|
561 using boost::math::cstdfloat::detail::atan2;
|
Chris@102
|
562 using boost::math::cstdfloat::detail::lgamma;
|
Chris@102
|
563 using boost::math::cstdfloat::detail::tgamma;
|
Chris@102
|
564 } // namespace std
|
Chris@102
|
565
|
Chris@102
|
566 // We will now remove the preprocessor symbols representing quadruple-precision <cmath>
|
Chris@102
|
567 // functions from the preprocessor.
|
Chris@102
|
568
|
Chris@102
|
569 #undef BOOST_CSTDFLOAT_FLOAT128_LDEXP
|
Chris@102
|
570 #undef BOOST_CSTDFLOAT_FLOAT128_FREXP
|
Chris@102
|
571 #undef BOOST_CSTDFLOAT_FLOAT128_FABS
|
Chris@102
|
572 #undef BOOST_CSTDFLOAT_FLOAT128_FLOOR
|
Chris@102
|
573 #undef BOOST_CSTDFLOAT_FLOAT128_CEIL
|
Chris@102
|
574 #undef BOOST_CSTDFLOAT_FLOAT128_SQRT
|
Chris@102
|
575 #undef BOOST_CSTDFLOAT_FLOAT128_TRUNC
|
Chris@102
|
576 #undef BOOST_CSTDFLOAT_FLOAT128_EXP
|
Chris@102
|
577 #undef BOOST_CSTDFLOAT_FLOAT128_EXPM1
|
Chris@102
|
578 #undef BOOST_CSTDFLOAT_FLOAT128_POW
|
Chris@102
|
579 #undef BOOST_CSTDFLOAT_FLOAT128_LOG
|
Chris@102
|
580 #undef BOOST_CSTDFLOAT_FLOAT128_LOG10
|
Chris@102
|
581 #undef BOOST_CSTDFLOAT_FLOAT128_SIN
|
Chris@102
|
582 #undef BOOST_CSTDFLOAT_FLOAT128_COS
|
Chris@102
|
583 #undef BOOST_CSTDFLOAT_FLOAT128_TAN
|
Chris@102
|
584 #undef BOOST_CSTDFLOAT_FLOAT128_ASIN
|
Chris@102
|
585 #undef BOOST_CSTDFLOAT_FLOAT128_ACOS
|
Chris@102
|
586 #undef BOOST_CSTDFLOAT_FLOAT128_ATAN
|
Chris@102
|
587 #undef BOOST_CSTDFLOAT_FLOAT128_SINH
|
Chris@102
|
588 #undef BOOST_CSTDFLOAT_FLOAT128_COSH
|
Chris@102
|
589 #undef BOOST_CSTDFLOAT_FLOAT128_TANH
|
Chris@102
|
590 #undef BOOST_CSTDFLOAT_FLOAT128_ASINH
|
Chris@102
|
591 #undef BOOST_CSTDFLOAT_FLOAT128_ACOSH
|
Chris@102
|
592 #undef BOOST_CSTDFLOAT_FLOAT128_ATANH
|
Chris@102
|
593 #undef BOOST_CSTDFLOAT_FLOAT128_FMOD
|
Chris@102
|
594 #undef BOOST_CSTDFLOAT_FLOAT128_ATAN2
|
Chris@102
|
595 #undef BOOST_CSTDFLOAT_FLOAT128_LGAMMA
|
Chris@102
|
596 #undef BOOST_CSTDFLOAT_FLOAT128_TGAMMA
|
Chris@102
|
597
|
Chris@102
|
598 #endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support)
|
Chris@102
|
599
|
Chris@102
|
600 #endif // _BOOST_CSTDFLOAT_CMATH_2014_02_15_HPP_
|