float128.hpp 31 KB

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