cstdfloat_cmath.hpp 69 KB

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