cstdfloat_cmath.hpp 72 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright Christopher Kormanyos 2014.
  3. // Copyright John Maddock 2014.
  4. // Copyright Paul Bristow 2014.
  5. // Distributed under the Boost Software License,
  6. // Version 1.0. (See accompanying file LICENSE_1_0.txt
  7. // or copy at http://www.boost.org/LICENSE_1_0.txt)
  8. //
  9. // Implement quadruple-precision <cmath> support.
  10. #ifndef _BOOST_CSTDFLOAT_CMATH_2014_02_15_HPP_
  11. #define _BOOST_CSTDFLOAT_CMATH_2014_02_15_HPP_
  12. #include <boost/math/cstdfloat/cstdfloat_types.hpp>
  13. #include <boost/math/cstdfloat/cstdfloat_limits.hpp>
  14. #if defined(BOOST_CSTDFLOAT_HAS_INTERNAL_FLOAT128_T) && defined(BOOST_MATH_USE_FLOAT128) && !defined(BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT)
  15. #include <cmath>
  16. #include <stdexcept>
  17. #include <iostream>
  18. #include <boost/cstdint.hpp>
  19. #include <boost/static_assert.hpp>
  20. #include <boost/throw_exception.hpp>
  21. #include <boost/core/enable_if.hpp>
  22. #include <boost/type_traits/is_same.hpp>
  23. #include <boost/type_traits/is_convertible.hpp>
  24. #include <boost/scoped_array.hpp>
  25. #if defined(_WIN32) && defined(__GNUC__)
  26. // Several versions of Mingw and probably cygwin too have broken
  27. // libquadmath implementations that segfault as soon as you call
  28. // expq or any function that depends on it.
  29. #define BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS
  30. #endif
  31. // Here is a helper function used for raising the value of a given
  32. // floating-point type to the power of n, where n has integral type.
  33. namespace boost {
  34. namespace math {
  35. namespace cstdfloat {
  36. namespace detail {
  37. template<class float_type, class integer_type>
  38. inline float_type pown(const float_type& x, const integer_type p)
  39. {
  40. const bool isneg = (x < 0);
  41. const bool isnan = (x != x);
  42. const bool isinf = ((!isneg) ? bool(+x > (std::numeric_limits<float_type>::max)())
  43. : bool(-x > (std::numeric_limits<float_type>::max)()));
  44. if (isnan) { return x; }
  45. if (isinf) { return std::numeric_limits<float_type>::quiet_NaN(); }
  46. const bool x_is_neg = (x < 0);
  47. const float_type abs_x = (x_is_neg ? -x : x);
  48. if (p < static_cast<integer_type>(0))
  49. {
  50. if (abs_x < (std::numeric_limits<float_type>::min)())
  51. {
  52. return (x_is_neg ? -std::numeric_limits<float_type>::infinity()
  53. : +std::numeric_limits<float_type>::infinity());
  54. }
  55. else
  56. {
  57. return float_type(1) / pown(x, static_cast<integer_type>(-p));
  58. }
  59. }
  60. if (p == static_cast<integer_type>(0))
  61. {
  62. return float_type(1);
  63. }
  64. else
  65. {
  66. if (p == static_cast<integer_type>(1)) { return x; }
  67. if (abs_x > (std::numeric_limits<float_type>::max)())
  68. {
  69. return (x_is_neg ? -std::numeric_limits<float_type>::infinity()
  70. : +std::numeric_limits<float_type>::infinity());
  71. }
  72. if (p == static_cast<integer_type>(2)) { return (x * x); }
  73. else if (p == static_cast<integer_type>(3)) { return ((x * x) * x); }
  74. else if (p == static_cast<integer_type>(4)) { const float_type x2 = (x * x); return (x2 * x2); }
  75. else
  76. {
  77. // The variable xn stores the binary powers of x.
  78. float_type result(((p % integer_type(2)) != integer_type(0)) ? x : float_type(1));
  79. float_type xn(x);
  80. integer_type p2 = p;
  81. while (integer_type(p2 /= 2) != integer_type(0))
  82. {
  83. // Square xn for each binary power.
  84. xn *= xn;
  85. const bool has_binary_power = (integer_type(p2 % integer_type(2)) != integer_type(0));
  86. if (has_binary_power)
  87. {
  88. // Multiply the result with each binary power contained in the exponent.
  89. result *= xn;
  90. }
  91. }
  92. return result;
  93. }
  94. }
  95. }
  96. }
  97. }
  98. }
  99. } // boost::math::cstdfloat::detail
  100. // We will now define preprocessor symbols representing quadruple-precision <cmath> functions.
  101. #if defined(BOOST_INTEL)
  102. #define BOOST_CSTDFLOAT_FLOAT128_LDEXP __ldexpq
  103. #define BOOST_CSTDFLOAT_FLOAT128_FREXP __frexpq
  104. #define BOOST_CSTDFLOAT_FLOAT128_FABS __fabsq
  105. #define BOOST_CSTDFLOAT_FLOAT128_FLOOR __floorq
  106. #define BOOST_CSTDFLOAT_FLOAT128_CEIL __ceilq
  107. #if !defined(BOOST_CSTDFLOAT_FLOAT128_SQRT)
  108. #define BOOST_CSTDFLOAT_FLOAT128_SQRT __sqrtq
  109. #endif
  110. #define BOOST_CSTDFLOAT_FLOAT128_TRUNC __truncq
  111. #define BOOST_CSTDFLOAT_FLOAT128_EXP __expq
  112. #define BOOST_CSTDFLOAT_FLOAT128_EXPM1 __expm1q
  113. #define BOOST_CSTDFLOAT_FLOAT128_POW __powq
  114. #define BOOST_CSTDFLOAT_FLOAT128_LOG __logq
  115. #define BOOST_CSTDFLOAT_FLOAT128_LOG10 __log10q
  116. #define BOOST_CSTDFLOAT_FLOAT128_SIN __sinq
  117. #define BOOST_CSTDFLOAT_FLOAT128_COS __cosq
  118. #define BOOST_CSTDFLOAT_FLOAT128_TAN __tanq
  119. #define BOOST_CSTDFLOAT_FLOAT128_ASIN __asinq
  120. #define BOOST_CSTDFLOAT_FLOAT128_ACOS __acosq
  121. #define BOOST_CSTDFLOAT_FLOAT128_ATAN __atanq
  122. #define BOOST_CSTDFLOAT_FLOAT128_SINH __sinhq
  123. #define BOOST_CSTDFLOAT_FLOAT128_COSH __coshq
  124. #define BOOST_CSTDFLOAT_FLOAT128_TANH __tanhq
  125. #define BOOST_CSTDFLOAT_FLOAT128_ASINH __asinhq
  126. #define BOOST_CSTDFLOAT_FLOAT128_ACOSH __acoshq
  127. #define BOOST_CSTDFLOAT_FLOAT128_ATANH __atanhq
  128. #define BOOST_CSTDFLOAT_FLOAT128_FMOD __fmodq
  129. #define BOOST_CSTDFLOAT_FLOAT128_ATAN2 __atan2q
  130. #define BOOST_CSTDFLOAT_FLOAT128_LGAMMA __lgammaq
  131. #define BOOST_CSTDFLOAT_FLOAT128_TGAMMA __tgammaq
  132. // begin more functions
  133. #define BOOST_CSTDFLOAT_FLOAT128_REMAINDER __remainderq
  134. #define BOOST_CSTDFLOAT_FLOAT128_REMQUO __remquoq
  135. #define BOOST_CSTDFLOAT_FLOAT128_FMA __fmaq
  136. #define BOOST_CSTDFLOAT_FLOAT128_FMAX __fmaxq
  137. #define BOOST_CSTDFLOAT_FLOAT128_FMIN __fminq
  138. #define BOOST_CSTDFLOAT_FLOAT128_FDIM __fdimq
  139. #define BOOST_CSTDFLOAT_FLOAT128_NAN __nanq
  140. //#define BOOST_CSTDFLOAT_FLOAT128_EXP2 __exp2q
  141. #define BOOST_CSTDFLOAT_FLOAT128_LOG2 __log2q
  142. #define BOOST_CSTDFLOAT_FLOAT128_LOG1P __log1pq
  143. #define BOOST_CSTDFLOAT_FLOAT128_CBRT __cbrtq
  144. #define BOOST_CSTDFLOAT_FLOAT128_HYPOT __hypotq
  145. #define BOOST_CSTDFLOAT_FLOAT128_ERF __erfq
  146. #define BOOST_CSTDFLOAT_FLOAT128_ERFC __erfcq
  147. #define BOOST_CSTDFLOAT_FLOAT128_LLROUND __llroundq
  148. #define BOOST_CSTDFLOAT_FLOAT128_LROUND __lroundq
  149. #define BOOST_CSTDFLOAT_FLOAT128_ROUND __roundq
  150. #define BOOST_CSTDFLOAT_FLOAT128_NEARBYINT __nearbyintq
  151. #define BOOST_CSTDFLOAT_FLOAT128_LLRINT __llrintq
  152. #define BOOST_CSTDFLOAT_FLOAT128_LRINT __lrintq
  153. #define BOOST_CSTDFLOAT_FLOAT128_RINT __rintq
  154. #define BOOST_CSTDFLOAT_FLOAT128_MODF __modfq
  155. #define BOOST_CSTDFLOAT_FLOAT128_SCALBLN __scalblnq
  156. #define BOOST_CSTDFLOAT_FLOAT128_SCALBN __scalbnq
  157. #define BOOST_CSTDFLOAT_FLOAT128_ILOGB __ilogbq
  158. #define BOOST_CSTDFLOAT_FLOAT128_LOGB __logbq
  159. #define BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER __nextafterq
  160. //#define BOOST_CSTDFLOAT_FLOAT128_NEXTTOWARD __nexttowardq
  161. #define BOOST_CSTDFLOAT_FLOAT128_COPYSIGN __copysignq
  162. #define BOOST_CSTDFLOAT_FLOAT128_SIGNBIT __signbitq
  163. //#define BOOST_CSTDFLOAT_FLOAT128_FPCLASSIFY __fpclassifyq
  164. //#define BOOST_CSTDFLOAT_FLOAT128_ISFINITE __isfiniteq
  165. #define BOOST_CSTDFLOAT_FLOAT128_ISINF __isinfq
  166. #define BOOST_CSTDFLOAT_FLOAT128_ISNAN __isnanq
  167. //#define BOOST_CSTDFLOAT_FLOAT128_ISNORMAL __isnormalq
  168. //#define BOOST_CSTDFLOAT_FLOAT128_ISGREATER __isgreaterq
  169. //#define BOOST_CSTDFLOAT_FLOAT128_ISGREATEREQUAL __isgreaterequalq
  170. //#define BOOST_CSTDFLOAT_FLOAT128_ISLESS __islessq
  171. //#define BOOST_CSTDFLOAT_FLOAT128_ISLESSEQUAL __islessequalq
  172. //#define BOOST_CSTDFLOAT_FLOAT128_ISLESSGREATER __islessgreaterq
  173. //#define BOOST_CSTDFLOAT_FLOAT128_ISUNORDERED __isunorderedq
  174. // end more functions
  175. #elif defined(__GNUC__)
  176. #define BOOST_CSTDFLOAT_FLOAT128_LDEXP ldexpq
  177. #define BOOST_CSTDFLOAT_FLOAT128_FREXP frexpq
  178. #define BOOST_CSTDFLOAT_FLOAT128_FABS fabsq
  179. #define BOOST_CSTDFLOAT_FLOAT128_FLOOR floorq
  180. #define BOOST_CSTDFLOAT_FLOAT128_CEIL ceilq
  181. #if !defined(BOOST_CSTDFLOAT_FLOAT128_SQRT)
  182. #define BOOST_CSTDFLOAT_FLOAT128_SQRT sqrtq
  183. #endif
  184. #define BOOST_CSTDFLOAT_FLOAT128_TRUNC truncq
  185. #define BOOST_CSTDFLOAT_FLOAT128_POW powq
  186. #define BOOST_CSTDFLOAT_FLOAT128_LOG logq
  187. #define BOOST_CSTDFLOAT_FLOAT128_LOG10 log10q
  188. #define BOOST_CSTDFLOAT_FLOAT128_SIN sinq
  189. #define BOOST_CSTDFLOAT_FLOAT128_COS cosq
  190. #define BOOST_CSTDFLOAT_FLOAT128_TAN tanq
  191. #define BOOST_CSTDFLOAT_FLOAT128_ASIN asinq
  192. #define BOOST_CSTDFLOAT_FLOAT128_ACOS acosq
  193. #define BOOST_CSTDFLOAT_FLOAT128_ATAN atanq
  194. #define BOOST_CSTDFLOAT_FLOAT128_FMOD fmodq
  195. #define BOOST_CSTDFLOAT_FLOAT128_ATAN2 atan2q
  196. #define BOOST_CSTDFLOAT_FLOAT128_LGAMMA lgammaq
  197. #if !defined(BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS)
  198. #define BOOST_CSTDFLOAT_FLOAT128_EXP expq
  199. #define BOOST_CSTDFLOAT_FLOAT128_EXPM1 expm1q
  200. #define BOOST_CSTDFLOAT_FLOAT128_SINH sinhq
  201. #define BOOST_CSTDFLOAT_FLOAT128_COSH coshq
  202. #define BOOST_CSTDFLOAT_FLOAT128_TANH tanhq
  203. #define BOOST_CSTDFLOAT_FLOAT128_ASINH asinhq
  204. #define BOOST_CSTDFLOAT_FLOAT128_ACOSH acoshq
  205. #define BOOST_CSTDFLOAT_FLOAT128_ATANH atanhq
  206. #define BOOST_CSTDFLOAT_FLOAT128_TGAMMA tgammaq
  207. #else // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS
  208. #define BOOST_CSTDFLOAT_FLOAT128_EXP expq_patch
  209. #define BOOST_CSTDFLOAT_FLOAT128_SINH sinhq_patch
  210. #define BOOST_CSTDFLOAT_FLOAT128_COSH coshq_patch
  211. #define BOOST_CSTDFLOAT_FLOAT128_TANH tanhq_patch
  212. #define BOOST_CSTDFLOAT_FLOAT128_ASINH asinhq_patch
  213. #define BOOST_CSTDFLOAT_FLOAT128_ACOSH acoshq_patch
  214. #define BOOST_CSTDFLOAT_FLOAT128_ATANH atanhq_patch
  215. #define BOOST_CSTDFLOAT_FLOAT128_TGAMMA tgammaq_patch
  216. #endif // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS
  217. // begin more functions
  218. #define BOOST_CSTDFLOAT_FLOAT128_REMAINDER remainderq
  219. #define BOOST_CSTDFLOAT_FLOAT128_REMQUO remquoq
  220. #define BOOST_CSTDFLOAT_FLOAT128_FMA fmaq
  221. #define BOOST_CSTDFLOAT_FLOAT128_FMAX fmaxq
  222. #define BOOST_CSTDFLOAT_FLOAT128_FMIN fminq
  223. #define BOOST_CSTDFLOAT_FLOAT128_FDIM fdimq
  224. #define BOOST_CSTDFLOAT_FLOAT128_NAN nanq
  225. //#define BOOST_CSTDFLOAT_FLOAT128_EXP2 exp2q
  226. #define BOOST_CSTDFLOAT_FLOAT128_LOG2 log2q
  227. #define BOOST_CSTDFLOAT_FLOAT128_LOG1P log1pq
  228. #define BOOST_CSTDFLOAT_FLOAT128_CBRT cbrtq
  229. #define BOOST_CSTDFLOAT_FLOAT128_HYPOT hypotq
  230. #define BOOST_CSTDFLOAT_FLOAT128_ERF erfq
  231. #define BOOST_CSTDFLOAT_FLOAT128_ERFC erfcq
  232. #define BOOST_CSTDFLOAT_FLOAT128_LLROUND llroundq
  233. #define BOOST_CSTDFLOAT_FLOAT128_LROUND lroundq
  234. #define BOOST_CSTDFLOAT_FLOAT128_ROUND roundq
  235. #define BOOST_CSTDFLOAT_FLOAT128_NEARBYINT nearbyintq
  236. #define BOOST_CSTDFLOAT_FLOAT128_LLRINT llrintq
  237. #define BOOST_CSTDFLOAT_FLOAT128_LRINT lrintq
  238. #define BOOST_CSTDFLOAT_FLOAT128_RINT rintq
  239. #define BOOST_CSTDFLOAT_FLOAT128_MODF modfq
  240. #define BOOST_CSTDFLOAT_FLOAT128_SCALBLN scalblnq
  241. #define BOOST_CSTDFLOAT_FLOAT128_SCALBN scalbnq
  242. #define BOOST_CSTDFLOAT_FLOAT128_ILOGB ilogbq
  243. #define BOOST_CSTDFLOAT_FLOAT128_LOGB logbq
  244. #define BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER nextafterq
  245. //#define BOOST_CSTDFLOAT_FLOAT128_NEXTTOWARD nexttowardq
  246. #define BOOST_CSTDFLOAT_FLOAT128_COPYSIGN copysignq
  247. #define BOOST_CSTDFLOAT_FLOAT128_SIGNBIT signbitq
  248. //#define BOOST_CSTDFLOAT_FLOAT128_FPCLASSIFY fpclassifyq
  249. //#define BOOST_CSTDFLOAT_FLOAT128_ISFINITE isfiniteq
  250. #define BOOST_CSTDFLOAT_FLOAT128_ISINF isinfq
  251. #define BOOST_CSTDFLOAT_FLOAT128_ISNAN isnanq
  252. //#define BOOST_CSTDFLOAT_FLOAT128_ISNORMAL isnormalq
  253. //#define BOOST_CSTDFLOAT_FLOAT128_ISGREATER isgreaterq
  254. //#define BOOST_CSTDFLOAT_FLOAT128_ISGREATEREQUAL isgreaterequalq
  255. //#define BOOST_CSTDFLOAT_FLOAT128_ISLESS islessq
  256. //#define BOOST_CSTDFLOAT_FLOAT128_ISLESSEQUAL islessequalq
  257. //#define BOOST_CSTDFLOAT_FLOAT128_ISLESSGREATER islessgreaterq
  258. //#define BOOST_CSTDFLOAT_FLOAT128_ISUNORDERED isunorderedq
  259. // end more functions
  260. #endif
  261. // Implement quadruple-precision <cmath> functions in the namespace
  262. // boost::math::cstdfloat::detail. Subsequently inject these into the
  263. // std namespace via *using* directive.
  264. // Begin with some forward function declarations. Also implement patches
  265. // for compilers that have broken float128 exponential functions.
  266. extern "C" int quadmath_snprintf(char*, std::size_t, const char*, ...) throw();
  267. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LDEXP(boost::math::cstdfloat::detail::float_internal128_t, int) throw();
  268. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FREXP(boost::math::cstdfloat::detail::float_internal128_t, int*) throw();
  269. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FABS(boost::math::cstdfloat::detail::float_internal128_t) throw();
  270. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FLOOR(boost::math::cstdfloat::detail::float_internal128_t) throw();
  271. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_CEIL(boost::math::cstdfloat::detail::float_internal128_t) throw();
  272. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SQRT(boost::math::cstdfloat::detail::float_internal128_t) throw();
  273. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TRUNC(boost::math::cstdfloat::detail::float_internal128_t) throw();
  274. 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();
  275. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOG(boost::math::cstdfloat::detail::float_internal128_t) throw();
  276. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOG10(boost::math::cstdfloat::detail::float_internal128_t) throw();
  277. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SIN(boost::math::cstdfloat::detail::float_internal128_t) throw();
  278. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COS(boost::math::cstdfloat::detail::float_internal128_t) throw();
  279. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TAN(boost::math::cstdfloat::detail::float_internal128_t) throw();
  280. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ASIN(boost::math::cstdfloat::detail::float_internal128_t) throw();
  281. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ACOS(boost::math::cstdfloat::detail::float_internal128_t) throw();
  282. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATAN(boost::math::cstdfloat::detail::float_internal128_t) throw();
  283. 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();
  284. 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();
  285. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LGAMMA(boost::math::cstdfloat::detail::float_internal128_t) throw();
  286. // begin more functions
  287. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_REMAINDER(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw();
  288. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_REMQUO(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t, int*) throw();
  289. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FMA(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw();
  290. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FMAX(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw();
  291. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FMIN(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw();
  292. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_FDIM(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw();
  293. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_NAN(const char*) throw();
  294. //extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP2 (boost::math::cstdfloat::detail::float_internal128_t) throw();
  295. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOG2(boost::math::cstdfloat::detail::float_internal128_t) throw();
  296. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOG1P(boost::math::cstdfloat::detail::float_internal128_t) throw();
  297. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_CBRT(boost::math::cstdfloat::detail::float_internal128_t) throw();
  298. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_HYPOT(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw();
  299. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ERF(boost::math::cstdfloat::detail::float_internal128_t) throw();
  300. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ERFC(boost::math::cstdfloat::detail::float_internal128_t) throw();
  301. extern "C" long long int BOOST_CSTDFLOAT_FLOAT128_LLROUND(boost::math::cstdfloat::detail::float_internal128_t) throw();
  302. extern "C" long int BOOST_CSTDFLOAT_FLOAT128_LROUND(boost::math::cstdfloat::detail::float_internal128_t) throw();
  303. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ROUND(boost::math::cstdfloat::detail::float_internal128_t) throw();
  304. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_NEARBYINT(boost::math::cstdfloat::detail::float_internal128_t) throw();
  305. extern "C" long long int BOOST_CSTDFLOAT_FLOAT128_LLRINT(boost::math::cstdfloat::detail::float_internal128_t) throw();
  306. extern "C" long int BOOST_CSTDFLOAT_FLOAT128_LRINT(boost::math::cstdfloat::detail::float_internal128_t) throw();
  307. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_RINT(boost::math::cstdfloat::detail::float_internal128_t) throw();
  308. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_MODF(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t*) throw();
  309. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SCALBLN(boost::math::cstdfloat::detail::float_internal128_t, long int) throw();
  310. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SCALBN(boost::math::cstdfloat::detail::float_internal128_t, int) throw();
  311. extern "C" int BOOST_CSTDFLOAT_FLOAT128_ILOGB(boost::math::cstdfloat::detail::float_internal128_t) throw();
  312. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_LOGB(boost::math::cstdfloat::detail::float_internal128_t) throw();
  313. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw();
  314. //extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_NEXTTOWARD (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw();
  315. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COPYSIGN(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw();
  316. extern "C" int BOOST_CSTDFLOAT_FLOAT128_SIGNBIT(boost::math::cstdfloat::detail::float_internal128_t) throw();
  317. //extern "C" int BOOST_CSTDFLOAT_FLOAT128_FPCLASSIFY (boost::math::cstdfloat::detail::float_internal128_t) throw();
  318. //extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISFINITE (boost::math::cstdfloat::detail::float_internal128_t) throw();
  319. extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISINF(boost::math::cstdfloat::detail::float_internal128_t) throw();
  320. extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISNAN(boost::math::cstdfloat::detail::float_internal128_t) throw();
  321. //extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ISNORMAL (boost::math::cstdfloat::detail::float_internal128_t) throw();
  322. //extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISGREATER (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw();
  323. //extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISGREATEREQUAL(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw();
  324. //extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISLESS (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw();
  325. //extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISLESSEQUAL (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw();
  326. //extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISLESSGREATER(boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw();
  327. //extern "C" int BOOST_CSTDFLOAT_FLOAT128_ISUNORDERED (boost::math::cstdfloat::detail::float_internal128_t, boost::math::cstdfloat::detail::float_internal128_t) throw();
  328. // end more functions
  329. #if !defined(BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS)
  330. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP(boost::math::cstdfloat::detail::float_internal128_t x) throw();
  331. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXPM1(boost::math::cstdfloat::detail::float_internal128_t x) throw();
  332. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SINH(boost::math::cstdfloat::detail::float_internal128_t x) throw();
  333. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COSH(boost::math::cstdfloat::detail::float_internal128_t x) throw();
  334. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TANH(boost::math::cstdfloat::detail::float_internal128_t x) throw();
  335. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ASINH(boost::math::cstdfloat::detail::float_internal128_t x) throw();
  336. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ACOSH(boost::math::cstdfloat::detail::float_internal128_t x) throw();
  337. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATANH(boost::math::cstdfloat::detail::float_internal128_t x) throw();
  338. extern "C" boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TGAMMA(boost::math::cstdfloat::detail::float_internal128_t x) throw();
  339. #else // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS
  340. // Forward declaration of the patched exponent function, exp(x).
  341. inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP(boost::math::cstdfloat::detail::float_internal128_t x);
  342. inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXPM1(boost::math::cstdfloat::detail::float_internal128_t x)
  343. {
  344. // Compute exp(x) - 1 for x small.
  345. // Use an order-36 polynomial approximation of the exponential function
  346. // in the range of (-ln2 < x < ln2). Scale the argument to this range
  347. // and subsequently multiply the result by 2^n accordingly.
  348. // Derive the polynomial coefficients with Mathematica(R) by generating
  349. // a table of high-precision values of exp(x) in the range (-ln2 < x < ln2)
  350. // and subsequently applying the built-in *Fit* function.
  351. // Table[{x, Exp[x] - 1}, {x, -Log[2], Log[2], 1/180}]
  352. // N[%, 120]
  353. // Fit[%, {x, x^2, x^3, x^4, x^5, x^6, x^7, x^8, x^9, x^10, x^11, x^12,
  354. // x^13, x^14, x^15, x^16, x^17, x^18, x^19, x^20, x^21, x^22,
  355. // x^23, x^24, x^25, x^26, x^27, x^28, x^29, x^30, x^31, x^32,
  356. // x^33, x^34, x^35, x^36}, x]
  357. typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
  358. float_type sum;
  359. if (x > BOOST_FLOAT128_C(0.693147180559945309417232121458176568075500134360255))
  360. {
  361. sum = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x) - float_type(1);
  362. }
  363. else
  364. {
  365. // Compute the polynomial approximation of exp(alpha).
  366. sum = ((((((((((((((((((((((((((((((((((((float_type(BOOST_FLOAT128_C(2.69291698127774166063293705964720493864630783729857438187365E-42)) * x
  367. + float_type(BOOST_FLOAT128_C(9.70937085471487654794114679403710456028986572118859594614033E-41))) * x
  368. + float_type(BOOST_FLOAT128_C(3.38715585158055097155585505318085512156885389014410753080500E-39))) * x
  369. + float_type(BOOST_FLOAT128_C(1.15162718532861050809222658798662695267019717760563645440433E-37))) * x
  370. + float_type(BOOST_FLOAT128_C(3.80039074689434663295873584133017767349635602413675471702393E-36))) * x
  371. + float_type(BOOST_FLOAT128_C(1.21612504934087520075905434734158045947460467096773246215239E-34))) * x
  372. + float_type(BOOST_FLOAT128_C(3.76998762883139753126119821241037824830069851253295480396224E-33))) * x
  373. + float_type(BOOST_FLOAT128_C(1.13099628863830344684998293828608215735777107850991029729440E-31))) * x
  374. + float_type(BOOST_FLOAT128_C(3.27988923706982293204067897468714277771890104022419696770352E-30))) * x
  375. + float_type(BOOST_FLOAT128_C(9.18368986379558482800593745627556950089950023355628325088207E-29))) * x
  376. + float_type(BOOST_FLOAT128_C(2.47959626322479746949155352659617642905315302382639380521497E-27))) * x
  377. + float_type(BOOST_FLOAT128_C(6.44695028438447337900255966737803112935639344283098705091949E-26))) * x
  378. + float_type(BOOST_FLOAT128_C(1.61173757109611834904452725462599961406036904573072897122957E-24))) * x
  379. + float_type(BOOST_FLOAT128_C(3.86817017063068403772269360016918092488847584660382953555804E-23))) * x
  380. + float_type(BOOST_FLOAT128_C(8.89679139245057328674891109315654704307721758924206107351744E-22))) * x
  381. + float_type(BOOST_FLOAT128_C(1.95729410633912612308475595397946731738088422488032228717097E-20))) * x
  382. + float_type(BOOST_FLOAT128_C(4.11031762331216485847799061511674191805055663711439605760231E-19))) * x
  383. + float_type(BOOST_FLOAT128_C(8.22063524662432971695598123977873600603370758794431071426640E-18))) * x
  384. + float_type(BOOST_FLOAT128_C(1.56192069685862264622163643500633782667263448653185159383285E-16))) * x
  385. + float_type(BOOST_FLOAT128_C(2.81145725434552076319894558300988749849555291507956994126835E-15))) * x
  386. + float_type(BOOST_FLOAT128_C(4.77947733238738529743820749111754320727153728139716409114011E-14))) * x
  387. + float_type(BOOST_FLOAT128_C(7.64716373181981647590113198578807092707697416852226691068627E-13))) * x
  388. + float_type(BOOST_FLOAT128_C(1.14707455977297247138516979786821056670509688396295740818677E-11))) * x
  389. + float_type(BOOST_FLOAT128_C(1.60590438368216145993923771701549479323291461578567184216302E-10))) * x
  390. + float_type(BOOST_FLOAT128_C(2.08767569878680989792100903212014323125428376052986408239620E-09))) * x
  391. + float_type(BOOST_FLOAT128_C(2.50521083854417187750521083854417187750523408006206780016659E-08))) * x
  392. + float_type(BOOST_FLOAT128_C(2.75573192239858906525573192239858906525573195144226062684604E-07))) * x
  393. + float_type(BOOST_FLOAT128_C(2.75573192239858906525573192239858906525573191310049321957902E-06))) * x
  394. + float_type(BOOST_FLOAT128_C(0.00002480158730158730158730158730158730158730158730149317774))) * x
  395. + float_type(BOOST_FLOAT128_C(0.00019841269841269841269841269841269841269841269841293575920))) * x
  396. + float_type(BOOST_FLOAT128_C(0.00138888888888888888888888888888888888888888888888889071045))) * x
  397. + float_type(BOOST_FLOAT128_C(0.00833333333333333333333333333333333333333333333333332986595))) * x
  398. + float_type(BOOST_FLOAT128_C(0.04166666666666666666666666666666666666666666666666666664876))) * x
  399. + float_type(BOOST_FLOAT128_C(0.16666666666666666666666666666666666666666666666666666669048))) * x
  400. + float_type(BOOST_FLOAT128_C(0.50000000000000000000000000000000000000000000000000000000006))) * x
  401. + float_type(BOOST_FLOAT128_C(0.99999999999999999999999999999999999999999999999999999999995))) * x);
  402. }
  403. return sum;
  404. }
  405. inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_EXP(boost::math::cstdfloat::detail::float_internal128_t x)
  406. {
  407. // Patch the expq() function for a subset of broken GCC compilers
  408. // like GCC 4.7, 4.8 on MinGW.
  409. // Use an order-36 polynomial approximation of the exponential function
  410. // in the range of (-ln2 < x < ln2). Scale the argument to this range
  411. // and subsequently multiply the result by 2^n accordingly.
  412. // Derive the polynomial coefficients with Mathematica(R) by generating
  413. // a table of high-precision values of exp(x) in the range (-ln2 < x < ln2)
  414. // and subsequently applying the built-in *Fit* function.
  415. // Table[{x, Exp[x] - 1}, {x, -Log[2], Log[2], 1/180}]
  416. // N[%, 120]
  417. // Fit[%, {x, x^2, x^3, x^4, x^5, x^6, x^7, x^8, x^9, x^10, x^11, x^12,
  418. // x^13, x^14, x^15, x^16, x^17, x^18, x^19, x^20, x^21, x^22,
  419. // x^23, x^24, x^25, x^26, x^27, x^28, x^29, x^30, x^31, x^32,
  420. // x^33, x^34, x^35, x^36}, x]
  421. typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
  422. // Scale the argument x to the range (-ln2 < x < ln2).
  423. BOOST_CONSTEXPR_OR_CONST float_type one_over_ln2 = float_type(BOOST_FLOAT128_C(1.44269504088896340735992468100189213742664595415299));
  424. const float_type x_over_ln2 = x * one_over_ln2;
  425. boost::int_fast32_t n;
  426. if (x != x)
  427. {
  428. // The argument is NaN.
  429. return std::numeric_limits<float_type>::quiet_NaN();
  430. }
  431. else if (::BOOST_CSTDFLOAT_FLOAT128_FABS(x) > BOOST_FLOAT128_C(+0.693147180559945309417232121458176568075500134360255))
  432. {
  433. // The absolute value of the argument exceeds ln2.
  434. n = static_cast<boost::int_fast32_t>(::BOOST_CSTDFLOAT_FLOAT128_FLOOR(x_over_ln2));
  435. }
  436. else if (::BOOST_CSTDFLOAT_FLOAT128_FABS(x) < BOOST_FLOAT128_C(+0.693147180559945309417232121458176568075500134360255))
  437. {
  438. // The absolute value of the argument is less than ln2.
  439. n = static_cast<boost::int_fast32_t>(0);
  440. }
  441. else
  442. {
  443. // The absolute value of the argument is exactly equal to ln2 (in the sense of floating-point equality).
  444. return float_type(2);
  445. }
  446. // Check if the argument is very near an integer.
  447. const float_type floor_of_x = ::BOOST_CSTDFLOAT_FLOAT128_FLOOR(x);
  448. if (::BOOST_CSTDFLOAT_FLOAT128_FABS(x - floor_of_x) < float_type(BOOST_CSTDFLOAT_FLOAT128_EPS))
  449. {
  450. // Return e^n for arguments very near an integer.
  451. return boost::math::cstdfloat::detail::pown(BOOST_FLOAT128_C(2.71828182845904523536028747135266249775724709369996), static_cast<boost::int_fast32_t>(floor_of_x));
  452. }
  453. // Compute the scaled argument alpha.
  454. const float_type alpha = x - (n * BOOST_FLOAT128_C(0.693147180559945309417232121458176568075500134360255));
  455. // Compute the polynomial approximation of expm1(alpha) and add to it
  456. // in order to obtain the scaled result.
  457. const float_type scaled_result = ::BOOST_CSTDFLOAT_FLOAT128_EXPM1(alpha) + float_type(1);
  458. // Rescale the result and return it.
  459. return scaled_result * boost::math::cstdfloat::detail::pown(float_type(2), n);
  460. }
  461. inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_SINH(boost::math::cstdfloat::detail::float_internal128_t x)
  462. {
  463. // Patch the sinhq() function for a subset of broken GCC compilers
  464. // like GCC 4.7, 4.8 on MinGW.
  465. typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
  466. // Here, we use the following:
  467. // Set: ex = exp(x)
  468. // Set: em1 = expm1(x)
  469. // Then
  470. // sinh(x) = (ex - 1/ex) / 2 ; for |x| >= 1
  471. // sinh(x) = (2em1 + em1^2) / (2ex) ; for |x| < 1
  472. const float_type ex = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x);
  473. if (::BOOST_CSTDFLOAT_FLOAT128_FABS(x) < float_type(+1))
  474. {
  475. const float_type em1 = ::BOOST_CSTDFLOAT_FLOAT128_EXPM1(x);
  476. return ((em1 * 2) + (em1 * em1)) / (ex * 2);
  477. }
  478. else
  479. {
  480. return (ex - (float_type(1) / ex)) / 2;
  481. }
  482. }
  483. inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_COSH(boost::math::cstdfloat::detail::float_internal128_t x)
  484. {
  485. // Patch the coshq() function for a subset of broken GCC compilers
  486. // like GCC 4.7, 4.8 on MinGW.
  487. typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
  488. const float_type ex = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x);
  489. return (ex + (float_type(1) / ex)) / 2;
  490. }
  491. inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TANH(boost::math::cstdfloat::detail::float_internal128_t x)
  492. {
  493. // Patch the tanhq() function for a subset of broken GCC compilers
  494. // like GCC 4.7, 4.8 on MinGW.
  495. typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
  496. const float_type ex_plus = ::BOOST_CSTDFLOAT_FLOAT128_EXP(x);
  497. const float_type ex_minus = (float_type(1) / ex_plus);
  498. return (ex_plus - ex_minus) / (ex_plus + ex_minus);
  499. }
  500. inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ASINH(boost::math::cstdfloat::detail::float_internal128_t x) throw()
  501. {
  502. // Patch the asinh() function since quadmath does not have it.
  503. typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
  504. return ::BOOST_CSTDFLOAT_FLOAT128_LOG(x + ::BOOST_CSTDFLOAT_FLOAT128_SQRT((x * x) + float_type(1)));
  505. }
  506. inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ACOSH(boost::math::cstdfloat::detail::float_internal128_t x) throw()
  507. {
  508. // Patch the acosh() function since quadmath does not have it.
  509. typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
  510. const float_type zp(x + float_type(1));
  511. const float_type zm(x - float_type(1));
  512. return ::BOOST_CSTDFLOAT_FLOAT128_LOG(x + (zp * ::BOOST_CSTDFLOAT_FLOAT128_SQRT(zm / zp)));
  513. }
  514. inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_ATANH(boost::math::cstdfloat::detail::float_internal128_t x) throw()
  515. {
  516. // Patch the atanh() function since quadmath does not have it.
  517. typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
  518. return (::BOOST_CSTDFLOAT_FLOAT128_LOG(float_type(1) + x)
  519. - ::BOOST_CSTDFLOAT_FLOAT128_LOG(float_type(1) - x)) / 2;
  520. }
  521. inline boost::math::cstdfloat::detail::float_internal128_t BOOST_CSTDFLOAT_FLOAT128_TGAMMA(boost::math::cstdfloat::detail::float_internal128_t x) throw()
  522. {
  523. // Patch the tgammaq() function for a subset of broken GCC compilers
  524. // like GCC 4.7, 4.8 on MinGW.
  525. typedef boost::math::cstdfloat::detail::float_internal128_t float_type;
  526. if (x > float_type(0))
  527. {
  528. return ::BOOST_CSTDFLOAT_FLOAT128_EXP(::BOOST_CSTDFLOAT_FLOAT128_LGAMMA(x));
  529. }
  530. else if (x < float_type(0))
  531. {
  532. // For x < 0, compute tgamma(-x) and use the reflection formula.
  533. const float_type positive_x = -x;
  534. float_type gamma_value = ::BOOST_CSTDFLOAT_FLOAT128_TGAMMA(positive_x);
  535. const float_type floor_of_positive_x = ::BOOST_CSTDFLOAT_FLOAT128_FLOOR(positive_x);
  536. // Take the reflection checks (slightly adapted) from <boost/math/gamma.hpp>.
  537. const bool floor_of_z_is_equal_to_z = (positive_x == ::BOOST_CSTDFLOAT_FLOAT128_FLOOR(positive_x));
  538. BOOST_CONSTEXPR_OR_CONST float_type my_pi = BOOST_FLOAT128_C(3.14159265358979323846264338327950288419716939937511);
  539. if (floor_of_z_is_equal_to_z)
  540. {
  541. const bool is_odd = ((boost::int32_t(floor_of_positive_x) % boost::int32_t(2)) != boost::int32_t(0));
  542. return (is_odd ? -std::numeric_limits<float_type>::infinity()
  543. : +std::numeric_limits<float_type>::infinity());
  544. }
  545. const float_type sinpx_value = x * ::BOOST_CSTDFLOAT_FLOAT128_SIN(my_pi * x);
  546. gamma_value *= sinpx_value;
  547. const bool result_is_too_large_to_represent = ((::BOOST_CSTDFLOAT_FLOAT128_FABS(gamma_value) < float_type(1))
  548. && (((std::numeric_limits<float_type>::max)() * ::BOOST_CSTDFLOAT_FLOAT128_FABS(gamma_value)) < my_pi));
  549. if (result_is_too_large_to_represent)
  550. {
  551. const bool is_odd = ((boost::int32_t(floor_of_positive_x) % boost::int32_t(2)) != boost::int32_t(0));
  552. return (is_odd ? -std::numeric_limits<float_type>::infinity()
  553. : +std::numeric_limits<float_type>::infinity());
  554. }
  555. gamma_value = -my_pi / gamma_value;
  556. if ((gamma_value > float_type(0)) || (gamma_value < float_type(0)))
  557. {
  558. return gamma_value;
  559. }
  560. else
  561. {
  562. // The value of gamma is too small to represent. Return 0.0 here.
  563. return float_type(0);
  564. }
  565. }
  566. else
  567. {
  568. // Gamma of zero is complex infinity. Return NaN here.
  569. return std::numeric_limits<float_type>::quiet_NaN();
  570. }
  571. }
  572. #endif // BOOST_CSTDFLOAT_BROKEN_FLOAT128_MATH_FUNCTIONS
  573. // Define the quadruple-precision <cmath> functions in the namespace boost::math::cstdfloat::detail.
  574. namespace boost {
  575. namespace math {
  576. namespace cstdfloat {
  577. namespace detail {
  578. 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); }
  579. 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); }
  580. inline boost::math::cstdfloat::detail::float_internal128_t fabs(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_FABS(x); }
  581. inline boost::math::cstdfloat::detail::float_internal128_t abs(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_FABS(x); }
  582. inline boost::math::cstdfloat::detail::float_internal128_t floor(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_FLOOR(x); }
  583. inline boost::math::cstdfloat::detail::float_internal128_t ceil(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_CEIL(x); }
  584. inline boost::math::cstdfloat::detail::float_internal128_t sqrt(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SQRT(x); }
  585. inline boost::math::cstdfloat::detail::float_internal128_t trunc(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TRUNC(x); }
  586. inline boost::math::cstdfloat::detail::float_internal128_t exp(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_EXP(x); }
  587. inline boost::math::cstdfloat::detail::float_internal128_t expm1(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_EXPM1(x); }
  588. 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); }
  589. 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)); }
  590. inline boost::math::cstdfloat::detail::float_internal128_t log(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOG(x); }
  591. inline boost::math::cstdfloat::detail::float_internal128_t log10(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOG10(x); }
  592. inline boost::math::cstdfloat::detail::float_internal128_t sin(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SIN(x); }
  593. inline boost::math::cstdfloat::detail::float_internal128_t cos(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_COS(x); }
  594. inline boost::math::cstdfloat::detail::float_internal128_t tan(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TAN(x); }
  595. inline boost::math::cstdfloat::detail::float_internal128_t asin(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ASIN(x); }
  596. inline boost::math::cstdfloat::detail::float_internal128_t acos(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ACOS(x); }
  597. inline boost::math::cstdfloat::detail::float_internal128_t atan(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ATAN(x); }
  598. inline boost::math::cstdfloat::detail::float_internal128_t sinh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SINH(x); }
  599. inline boost::math::cstdfloat::detail::float_internal128_t cosh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_COSH(x); }
  600. inline boost::math::cstdfloat::detail::float_internal128_t tanh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TANH(x); }
  601. inline boost::math::cstdfloat::detail::float_internal128_t asinh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ASINH(x); }
  602. inline boost::math::cstdfloat::detail::float_internal128_t acosh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ACOSH(x); }
  603. inline boost::math::cstdfloat::detail::float_internal128_t atanh(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ATANH(x); }
  604. 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); }
  605. 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); }
  606. inline boost::math::cstdfloat::detail::float_internal128_t lgamma(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LGAMMA(x); }
  607. inline boost::math::cstdfloat::detail::float_internal128_t tgamma(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_TGAMMA(x); }
  608. // begin more functions
  609. inline boost::math::cstdfloat::detail::float_internal128_t remainder(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_REMAINDER(x, y); }
  610. inline boost::math::cstdfloat::detail::float_internal128_t remquo(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y, int* z) { return ::BOOST_CSTDFLOAT_FLOAT128_REMQUO(x, y, z); }
  611. inline boost::math::cstdfloat::detail::float_internal128_t fma(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y, boost::math::cstdfloat::detail::float_internal128_t z) { return BOOST_CSTDFLOAT_FLOAT128_FMA(x, y, z); }
  612. inline boost::math::cstdfloat::detail::float_internal128_t fmax(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMAX(x, y); }
  613. template <class T>
  614. inline typename boost::enable_if_c<
  615. boost::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value
  616. && !boost::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type
  617. fmax(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMAX(x, y); }
  618. template <class T>
  619. inline typename boost::enable_if_c<
  620. boost::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value
  621. && !boost::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type
  622. fmax(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMAX(x, y); }
  623. inline boost::math::cstdfloat::detail::float_internal128_t fmin(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMIN(x, y); }
  624. template <class T>
  625. inline typename boost::enable_if_c<
  626. boost::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value
  627. && !boost::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type
  628. fmin(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMIN(x, y); }
  629. template <class T>
  630. inline typename boost::enable_if_c<
  631. boost::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value
  632. && !boost::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type
  633. fmin(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_FMIN(x, y); }
  634. inline boost::math::cstdfloat::detail::float_internal128_t fdim(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_FDIM(x, y); }
  635. inline boost::math::cstdfloat::detail::float_internal128_t nanq(const char* x) { return ::BOOST_CSTDFLOAT_FLOAT128_NAN(x); }
  636. inline boost::math::cstdfloat::detail::float_internal128_t exp2(boost::math::cstdfloat::detail::float_internal128_t x)
  637. {
  638. return ::BOOST_CSTDFLOAT_FLOAT128_POW(boost::math::cstdfloat::detail::float_internal128_t(2), x);
  639. }
  640. inline boost::math::cstdfloat::detail::float_internal128_t log2(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOG2(x); }
  641. inline boost::math::cstdfloat::detail::float_internal128_t log1p(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOG1P(x); }
  642. inline boost::math::cstdfloat::detail::float_internal128_t cbrt(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_CBRT(x); }
  643. inline boost::math::cstdfloat::detail::float_internal128_t hypot(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y, boost::math::cstdfloat::detail::float_internal128_t z) { return ::BOOST_CSTDFLOAT_FLOAT128_SQRT(x*x + y * y + z * z); }
  644. inline boost::math::cstdfloat::detail::float_internal128_t hypot(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_HYPOT(x, y); }
  645. template <class T>
  646. inline typename boost::enable_if_c<
  647. boost::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value
  648. && !boost::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type
  649. hypot(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return ::BOOST_CSTDFLOAT_FLOAT128_HYPOT(x, y); }
  650. template <class T>
  651. inline typename boost::enable_if_c<
  652. boost::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value
  653. && !boost::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type
  654. hypot(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_HYPOT(x, y); }
  655. inline boost::math::cstdfloat::detail::float_internal128_t erf(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ERF(x); }
  656. inline boost::math::cstdfloat::detail::float_internal128_t erfc(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ERFC(x); }
  657. inline long long int llround(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LLROUND(x); }
  658. inline long int lround(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LROUND(x); }
  659. inline boost::math::cstdfloat::detail::float_internal128_t round(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ROUND(x); }
  660. inline boost::math::cstdfloat::detail::float_internal128_t nearbyint(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_NEARBYINT(x); }
  661. inline long long int llrint(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LLRINT(x); }
  662. inline long int lrint(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LRINT(x); }
  663. inline boost::math::cstdfloat::detail::float_internal128_t rint(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_RINT(x); }
  664. inline boost::math::cstdfloat::detail::float_internal128_t modf(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t* y) { return ::BOOST_CSTDFLOAT_FLOAT128_MODF(x, y); }
  665. inline boost::math::cstdfloat::detail::float_internal128_t scalbln(boost::math::cstdfloat::detail::float_internal128_t x, long int y) { return ::BOOST_CSTDFLOAT_FLOAT128_SCALBLN(x, y); }
  666. inline boost::math::cstdfloat::detail::float_internal128_t scalbn(boost::math::cstdfloat::detail::float_internal128_t x, int y) { return ::BOOST_CSTDFLOAT_FLOAT128_SCALBN(x, y); }
  667. inline int ilogb(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ILOGB(x); }
  668. inline boost::math::cstdfloat::detail::float_internal128_t logb(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_LOGB(x); }
  669. inline boost::math::cstdfloat::detail::float_internal128_t nextafter(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER(x, y); }
  670. inline boost::math::cstdfloat::detail::float_internal128_t nexttoward(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return -(::BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER(-x, -y)); }
  671. inline boost::math::cstdfloat::detail::float_internal128_t copysign BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_COPYSIGN(x, y); }
  672. inline bool signbit BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_SIGNBIT(x); }
  673. inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x)
  674. {
  675. if (::BOOST_CSTDFLOAT_FLOAT128_ISNAN(x))
  676. return FP_NAN;
  677. else if (::BOOST_CSTDFLOAT_FLOAT128_ISINF(x))
  678. return FP_INFINITE;
  679. else if (x == BOOST_FLOAT128_C(0.0))
  680. return FP_ZERO;
  681. if (::BOOST_CSTDFLOAT_FLOAT128_FABS(x) < BOOST_CSTDFLOAT_FLOAT128_MIN)
  682. return FP_SUBNORMAL;
  683. else
  684. return FP_NORMAL;
  685. }
  686. inline bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x)
  687. {
  688. return !::BOOST_CSTDFLOAT_FLOAT128_ISNAN(x) && !::BOOST_CSTDFLOAT_FLOAT128_ISINF(x);
  689. }
  690. inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ISINF(x); }
  691. inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) { return ::BOOST_CSTDFLOAT_FLOAT128_ISNAN(x); }
  692. inline bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x) { return boost::math::cstdfloat::detail::fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(x) == FP_NORMAL; }
  693. inline bool isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y)
  694. {
  695. if (isnan BOOST_PREVENT_MACRO_SUBSTITUTION(x) || isnan BOOST_PREVENT_MACRO_SUBSTITUTION(y))
  696. return false;
  697. return x > y;
  698. }
  699. template <class T>
  700. inline typename boost::enable_if_c<
  701. boost::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value
  702. && !boost::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type
  703. isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); }
  704. template <class T>
  705. inline typename boost::enable_if_c<
  706. boost::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value
  707. && !boost::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type
  708. isgreater BOOST_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return isgreater BOOST_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); }
  709. inline bool isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y)
  710. {
  711. if (isnan BOOST_PREVENT_MACRO_SUBSTITUTION(x) || isnan BOOST_PREVENT_MACRO_SUBSTITUTION(y))
  712. return false;
  713. return x >= y;
  714. }
  715. template <class T>
  716. inline typename boost::enable_if_c<
  717. boost::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value
  718. && !boost::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type
  719. isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); }
  720. template <class T>
  721. inline typename boost::enable_if_c<
  722. boost::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value
  723. && !boost::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type
  724. isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return isgreaterequal BOOST_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); }
  725. inline bool isless BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y)
  726. {
  727. if (isnan BOOST_PREVENT_MACRO_SUBSTITUTION(x) || isnan BOOST_PREVENT_MACRO_SUBSTITUTION(y))
  728. return false;
  729. return x < y;
  730. }
  731. template <class T>
  732. inline typename boost::enable_if_c<
  733. boost::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value
  734. && !boost::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type
  735. isless BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return isless BOOST_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); }
  736. template <class T>
  737. inline typename boost::enable_if_c<
  738. boost::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value
  739. && !boost::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type
  740. isless BOOST_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return isless BOOST_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); }
  741. inline bool islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y)
  742. {
  743. if (isnan BOOST_PREVENT_MACRO_SUBSTITUTION(x) || isnan BOOST_PREVENT_MACRO_SUBSTITUTION(y))
  744. return false;
  745. return x <= y;
  746. }
  747. template <class T>
  748. inline typename boost::enable_if_c<
  749. boost::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value
  750. && !boost::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type
  751. islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); }
  752. template <class T>
  753. inline typename boost::enable_if_c<
  754. boost::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value
  755. && !boost::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type
  756. islessequal BOOST_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return islessequal BOOST_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); }
  757. inline bool islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y)
  758. {
  759. if (isnan BOOST_PREVENT_MACRO_SUBSTITUTION(x) || isnan BOOST_PREVENT_MACRO_SUBSTITUTION(y))
  760. return false;
  761. return (x < y) || (x > y);
  762. }
  763. template <class T>
  764. inline typename boost::enable_if_c<
  765. boost::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value
  766. && !boost::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type
  767. islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); }
  768. template <class T>
  769. inline typename boost::enable_if_c<
  770. boost::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value
  771. && !boost::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type
  772. islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return islessgreater BOOST_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); }
  773. inline bool isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, boost::math::cstdfloat::detail::float_internal128_t y) { return ::BOOST_CSTDFLOAT_FLOAT128_ISNAN(x) || ::BOOST_CSTDFLOAT_FLOAT128_ISNAN(y); }
  774. template <class T>
  775. inline typename boost::enable_if_c<
  776. boost::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value
  777. && !boost::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type
  778. isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(boost::math::cstdfloat::detail::float_internal128_t x, T y) { return isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(x, (boost::math::cstdfloat::detail::float_internal128_t)y); }
  779. template <class T>
  780. inline typename boost::enable_if_c<
  781. boost::is_convertible<T, boost::math::cstdfloat::detail::float_internal128_t>::value
  782. && !boost::is_same<T, boost::math::cstdfloat::detail::float_internal128_t>::value, boost::math::cstdfloat::detail::float_internal128_t>::type
  783. isunordered BOOST_PREVENT_MACRO_SUBSTITUTION(T x, boost::math::cstdfloat::detail::float_internal128_t y) { return isunordered BOOST_PREVENT_MACRO_SUBSTITUTION((boost::math::cstdfloat::detail::float_internal128_t)x, y); }
  784. // end more functions
  785. }
  786. }
  787. }
  788. } // boost::math::cstdfloat::detail
  789. // We will now inject the quadruple-precision <cmath> functions
  790. // into the std namespace. This is done via *using* directive.
  791. namespace std
  792. {
  793. using boost::math::cstdfloat::detail::ldexp;
  794. using boost::math::cstdfloat::detail::frexp;
  795. using boost::math::cstdfloat::detail::fabs;
  796. #if !(defined(_GLIBCXX_USE_FLOAT128) && defined(__GNUC__) && (__GNUC__ >= 7))
  797. using boost::math::cstdfloat::detail::abs;
  798. #endif
  799. using boost::math::cstdfloat::detail::floor;
  800. using boost::math::cstdfloat::detail::ceil;
  801. using boost::math::cstdfloat::detail::sqrt;
  802. using boost::math::cstdfloat::detail::trunc;
  803. using boost::math::cstdfloat::detail::exp;
  804. using boost::math::cstdfloat::detail::expm1;
  805. using boost::math::cstdfloat::detail::pow;
  806. using boost::math::cstdfloat::detail::log;
  807. using boost::math::cstdfloat::detail::log10;
  808. using boost::math::cstdfloat::detail::sin;
  809. using boost::math::cstdfloat::detail::cos;
  810. using boost::math::cstdfloat::detail::tan;
  811. using boost::math::cstdfloat::detail::asin;
  812. using boost::math::cstdfloat::detail::acos;
  813. using boost::math::cstdfloat::detail::atan;
  814. using boost::math::cstdfloat::detail::sinh;
  815. using boost::math::cstdfloat::detail::cosh;
  816. using boost::math::cstdfloat::detail::tanh;
  817. using boost::math::cstdfloat::detail::asinh;
  818. using boost::math::cstdfloat::detail::acosh;
  819. using boost::math::cstdfloat::detail::atanh;
  820. using boost::math::cstdfloat::detail::fmod;
  821. using boost::math::cstdfloat::detail::atan2;
  822. using boost::math::cstdfloat::detail::lgamma;
  823. using boost::math::cstdfloat::detail::tgamma;
  824. // begin more functions
  825. using boost::math::cstdfloat::detail::remainder;
  826. using boost::math::cstdfloat::detail::remquo;
  827. using boost::math::cstdfloat::detail::fma;
  828. using boost::math::cstdfloat::detail::fmax;
  829. using boost::math::cstdfloat::detail::fmin;
  830. using boost::math::cstdfloat::detail::fdim;
  831. using boost::math::cstdfloat::detail::nanq;
  832. using boost::math::cstdfloat::detail::exp2;
  833. using boost::math::cstdfloat::detail::log2;
  834. using boost::math::cstdfloat::detail::log1p;
  835. using boost::math::cstdfloat::detail::cbrt;
  836. using boost::math::cstdfloat::detail::hypot;
  837. using boost::math::cstdfloat::detail::erf;
  838. using boost::math::cstdfloat::detail::erfc;
  839. using boost::math::cstdfloat::detail::llround;
  840. using boost::math::cstdfloat::detail::lround;
  841. using boost::math::cstdfloat::detail::round;
  842. using boost::math::cstdfloat::detail::nearbyint;
  843. using boost::math::cstdfloat::detail::llrint;
  844. using boost::math::cstdfloat::detail::lrint;
  845. using boost::math::cstdfloat::detail::rint;
  846. using boost::math::cstdfloat::detail::modf;
  847. using boost::math::cstdfloat::detail::scalbln;
  848. using boost::math::cstdfloat::detail::scalbn;
  849. using boost::math::cstdfloat::detail::ilogb;
  850. using boost::math::cstdfloat::detail::logb;
  851. using boost::math::cstdfloat::detail::nextafter;
  852. using boost::math::cstdfloat::detail::nexttoward;
  853. using boost::math::cstdfloat::detail::copysign;
  854. using boost::math::cstdfloat::detail::signbit;
  855. using boost::math::cstdfloat::detail::fpclassify;
  856. using boost::math::cstdfloat::detail::isfinite;
  857. using boost::math::cstdfloat::detail::isinf;
  858. using boost::math::cstdfloat::detail::isnan;
  859. using boost::math::cstdfloat::detail::isnormal;
  860. using boost::math::cstdfloat::detail::isgreater;
  861. using boost::math::cstdfloat::detail::isgreaterequal;
  862. using boost::math::cstdfloat::detail::isless;
  863. using boost::math::cstdfloat::detail::islessequal;
  864. using boost::math::cstdfloat::detail::islessgreater;
  865. using boost::math::cstdfloat::detail::isunordered;
  866. // end more functions
  867. //
  868. // Very basic iostream operator:
  869. //
  870. inline std::ostream& operator << (std::ostream& os, __float128 m_value)
  871. {
  872. std::streamsize digits = os.precision();
  873. std::ios_base::fmtflags f = os.flags();
  874. std::string s;
  875. char buf[100];
  876. boost::scoped_array<char> buf2;
  877. std::string format = "%";
  878. if (f & std::ios_base::showpos)
  879. format += "+";
  880. if (f & std::ios_base::showpoint)
  881. format += "#";
  882. format += ".*";
  883. if (digits == 0)
  884. digits = 36;
  885. format += "Q";
  886. if (f & std::ios_base::scientific)
  887. format += "e";
  888. else if (f & std::ios_base::fixed)
  889. format += "f";
  890. else
  891. format += "g";
  892. int v = quadmath_snprintf(buf, 100, format.c_str(), digits, m_value);
  893. if ((v < 0) || (v >= 99))
  894. {
  895. int v_max = v;
  896. buf2.reset(new char[v + 3]);
  897. v = quadmath_snprintf(&buf2[0], v_max + 3, format.c_str(), digits, m_value);
  898. if (v >= v_max + 3)
  899. {
  900. BOOST_THROW_EXCEPTION(std::runtime_error("Formatting of float128_type failed."));
  901. }
  902. s = &buf2[0];
  903. }
  904. else
  905. s = buf;
  906. std::streamsize ss = os.width();
  907. if (ss > static_cast<std::streamsize>(s.size()))
  908. {
  909. char fill = os.fill();
  910. if ((os.flags() & std::ios_base::left) == std::ios_base::left)
  911. s.append(static_cast<std::string::size_type>(ss - s.size()), fill);
  912. else
  913. s.insert(static_cast<std::string::size_type>(0), static_cast<std::string::size_type>(ss - s.size()), fill);
  914. }
  915. return os << s;
  916. }
  917. } // namespace std
  918. // We will now remove the preprocessor symbols representing quadruple-precision <cmath>
  919. // functions from the preprocessor.
  920. #undef BOOST_CSTDFLOAT_FLOAT128_LDEXP
  921. #undef BOOST_CSTDFLOAT_FLOAT128_FREXP
  922. #undef BOOST_CSTDFLOAT_FLOAT128_FABS
  923. #undef BOOST_CSTDFLOAT_FLOAT128_FLOOR
  924. #undef BOOST_CSTDFLOAT_FLOAT128_CEIL
  925. #undef BOOST_CSTDFLOAT_FLOAT128_SQRT
  926. #undef BOOST_CSTDFLOAT_FLOAT128_TRUNC
  927. #undef BOOST_CSTDFLOAT_FLOAT128_EXP
  928. #undef BOOST_CSTDFLOAT_FLOAT128_EXPM1
  929. #undef BOOST_CSTDFLOAT_FLOAT128_POW
  930. #undef BOOST_CSTDFLOAT_FLOAT128_LOG
  931. #undef BOOST_CSTDFLOAT_FLOAT128_LOG10
  932. #undef BOOST_CSTDFLOAT_FLOAT128_SIN
  933. #undef BOOST_CSTDFLOAT_FLOAT128_COS
  934. #undef BOOST_CSTDFLOAT_FLOAT128_TAN
  935. #undef BOOST_CSTDFLOAT_FLOAT128_ASIN
  936. #undef BOOST_CSTDFLOAT_FLOAT128_ACOS
  937. #undef BOOST_CSTDFLOAT_FLOAT128_ATAN
  938. #undef BOOST_CSTDFLOAT_FLOAT128_SINH
  939. #undef BOOST_CSTDFLOAT_FLOAT128_COSH
  940. #undef BOOST_CSTDFLOAT_FLOAT128_TANH
  941. #undef BOOST_CSTDFLOAT_FLOAT128_ASINH
  942. #undef BOOST_CSTDFLOAT_FLOAT128_ACOSH
  943. #undef BOOST_CSTDFLOAT_FLOAT128_ATANH
  944. #undef BOOST_CSTDFLOAT_FLOAT128_FMOD
  945. #undef BOOST_CSTDFLOAT_FLOAT128_ATAN2
  946. #undef BOOST_CSTDFLOAT_FLOAT128_LGAMMA
  947. #undef BOOST_CSTDFLOAT_FLOAT128_TGAMMA
  948. // begin more functions
  949. #undef BOOST_CSTDFLOAT_FLOAT128_REMAINDER
  950. #undef BOOST_CSTDFLOAT_FLOAT128_REMQUO
  951. #undef BOOST_CSTDFLOAT_FLOAT128_FMA
  952. #undef BOOST_CSTDFLOAT_FLOAT128_FMAX
  953. #undef BOOST_CSTDFLOAT_FLOAT128_FMIN
  954. #undef BOOST_CSTDFLOAT_FLOAT128_FDIM
  955. #undef BOOST_CSTDFLOAT_FLOAT128_NAN
  956. #undef BOOST_CSTDFLOAT_FLOAT128_EXP2
  957. #undef BOOST_CSTDFLOAT_FLOAT128_LOG2
  958. #undef BOOST_CSTDFLOAT_FLOAT128_LOG1P
  959. #undef BOOST_CSTDFLOAT_FLOAT128_CBRT
  960. #undef BOOST_CSTDFLOAT_FLOAT128_HYPOT
  961. #undef BOOST_CSTDFLOAT_FLOAT128_ERF
  962. #undef BOOST_CSTDFLOAT_FLOAT128_ERFC
  963. #undef BOOST_CSTDFLOAT_FLOAT128_LLROUND
  964. #undef BOOST_CSTDFLOAT_FLOAT128_LROUND
  965. #undef BOOST_CSTDFLOAT_FLOAT128_ROUND
  966. #undef BOOST_CSTDFLOAT_FLOAT128_NEARBYINT
  967. #undef BOOST_CSTDFLOAT_FLOAT128_LLRINT
  968. #undef BOOST_CSTDFLOAT_FLOAT128_LRINT
  969. #undef BOOST_CSTDFLOAT_FLOAT128_RINT
  970. #undef BOOST_CSTDFLOAT_FLOAT128_MODF
  971. #undef BOOST_CSTDFLOAT_FLOAT128_SCALBLN
  972. #undef BOOST_CSTDFLOAT_FLOAT128_SCALBN
  973. #undef BOOST_CSTDFLOAT_FLOAT128_ILOGB
  974. #undef BOOST_CSTDFLOAT_FLOAT128_LOGB
  975. #undef BOOST_CSTDFLOAT_FLOAT128_NEXTAFTER
  976. #undef BOOST_CSTDFLOAT_FLOAT128_NEXTTOWARD
  977. #undef BOOST_CSTDFLOAT_FLOAT128_COPYSIGN
  978. #undef BOOST_CSTDFLOAT_FLOAT128_SIGNBIT
  979. #undef BOOST_CSTDFLOAT_FLOAT128_FPCLASSIFY
  980. #undef BOOST_CSTDFLOAT_FLOAT128_ISFINITE
  981. #undef BOOST_CSTDFLOAT_FLOAT128_ISINF
  982. #undef BOOST_CSTDFLOAT_FLOAT128_ISNAN
  983. #undef BOOST_CSTDFLOAT_FLOAT128_ISNORMAL
  984. #undef BOOST_CSTDFLOAT_FLOAT128_ISGREATER
  985. #undef BOOST_CSTDFLOAT_FLOAT128_ISGREATEREQUAL
  986. #undef BOOST_CSTDFLOAT_FLOAT128_ISLESS
  987. #undef BOOST_CSTDFLOAT_FLOAT128_ISLESSEQUAL
  988. #undef BOOST_CSTDFLOAT_FLOAT128_ISLESSGREATER
  989. #undef BOOST_CSTDFLOAT_FLOAT128_ISUNORDERED
  990. // end more functions
  991. #endif // Not BOOST_CSTDFLOAT_NO_LIBQUADMATH_SUPPORT (i.e., the user would like to have libquadmath support)
  992. #endif // _BOOST_CSTDFLOAT_CMATH_2014_02_15_HPP_