annotate DEPENDENCIES/generic/include/boost/multiprecision/mpfi.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents c530137014c0
children
rev   line source
Chris@16 1 ///////////////////////////////////////////////////////////////////////////////
Chris@16 2 // Copyright 2011 John Maddock. Distributed under the Boost
Chris@16 3 // Software License, Version 1.0. (See accompanying file
Chris@16 4 // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
Chris@16 5
Chris@16 6 #ifndef BOOST_MATH_BN_MPFI_HPP
Chris@16 7 #define BOOST_MATH_BN_MPFI_HPP
Chris@16 8
Chris@16 9 #include <boost/multiprecision/number.hpp>
Chris@16 10 #include <boost/math/special_functions/fpclassify.hpp>
Chris@16 11 #include <boost/cstdint.hpp>
Chris@16 12 #include <boost/multiprecision/detail/big_lanczos.hpp>
Chris@16 13 #include <boost/multiprecision/detail/digits.hpp>
Chris@16 14 #include <boost/multiprecision/mpfr.hpp>
Chris@16 15 #include <boost/math/constants/constants.hpp>
Chris@16 16 #include <mpfi.h>
Chris@16 17 #include <cmath>
Chris@16 18 #include <algorithm>
Chris@16 19
Chris@16 20 namespace boost{
Chris@16 21 namespace multiprecision{
Chris@16 22 namespace backends{
Chris@16 23
Chris@16 24 template <unsigned digits10>
Chris@16 25 struct mpfi_float_backend;
Chris@16 26
Chris@16 27 } // namespace backends
Chris@16 28
Chris@16 29 template <unsigned digits10>
Chris@16 30 struct number_category<backends::mpfi_float_backend<digits10> > : public mpl::int_<number_kind_floating_point>{};
Chris@16 31
Chris@16 32 struct interval_error : public std::runtime_error
Chris@16 33 {
Chris@16 34 interval_error(const std::string& s) : std::runtime_error(s) {}
Chris@16 35 };
Chris@16 36
Chris@16 37 namespace backends{
Chris@16 38
Chris@16 39 namespace detail{
Chris@16 40
Chris@16 41 inline int mpfi_sgn(mpfi_srcptr p)
Chris@16 42 {
Chris@16 43 if(mpfi_is_zero(p))
Chris@16 44 return 0;
Chris@16 45 if(mpfi_is_strictly_pos(p))
Chris@16 46 return 1;
Chris@16 47 if(mpfi_is_strictly_neg(p))
Chris@16 48 return -1;
Chris@16 49 BOOST_THROW_EXCEPTION(interval_error("Sign of interval is ambiguous."));
Chris@16 50 }
Chris@16 51
Chris@16 52 template <unsigned digits10>
Chris@16 53 struct mpfi_float_imp;
Chris@16 54
Chris@16 55 template <unsigned digits10>
Chris@16 56 struct mpfi_float_imp
Chris@16 57 {
Chris@16 58 typedef mpl::list<long, long long> signed_types;
Chris@16 59 typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
Chris@16 60 typedef mpl::list<double, long double> float_types;
Chris@16 61 typedef long exponent_type;
Chris@16 62
Chris@16 63 mpfi_float_imp()
Chris@16 64 {
Chris@16 65 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 66 }
Chris@16 67 mpfi_float_imp(unsigned prec)
Chris@16 68 {
Chris@16 69 mpfi_init2(m_data, prec);
Chris@16 70 }
Chris@16 71
Chris@16 72 mpfi_float_imp(const mpfi_float_imp& o)
Chris@16 73 {
Chris@16 74 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 75 if(o.m_data[0].left._mpfr_d)
Chris@16 76 mpfi_set(m_data, o.m_data);
Chris@16 77 }
Chris@16 78 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@16 79 mpfi_float_imp(mpfi_float_imp&& o) BOOST_NOEXCEPT
Chris@16 80 {
Chris@16 81 m_data[0] = o.m_data[0];
Chris@16 82 o.m_data[0].left._mpfr_d = 0;
Chris@16 83 }
Chris@16 84 #endif
Chris@16 85 mpfi_float_imp& operator = (const mpfi_float_imp& o)
Chris@16 86 {
Chris@16 87 if(m_data[0].left._mpfr_d == 0)
Chris@16 88 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 89 if(o.m_data[0].left._mpfr_d)
Chris@16 90 mpfi_set(m_data, o.m_data);
Chris@16 91 return *this;
Chris@16 92 }
Chris@16 93 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@16 94 mpfi_float_imp& operator = (mpfi_float_imp&& o) BOOST_NOEXCEPT
Chris@16 95 {
Chris@16 96 mpfi_swap(m_data, o.m_data);
Chris@16 97 return *this;
Chris@16 98 }
Chris@16 99 #endif
Chris@16 100 #ifdef _MPFR_H_HAVE_INTMAX_T
Chris@16 101 mpfi_float_imp& operator = (unsigned long long i)
Chris@16 102 {
Chris@16 103 if(m_data[0].left._mpfr_d == 0)
Chris@16 104 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 105 mpfr_set_uj(left_data(), i, GMP_RNDD);
Chris@16 106 mpfr_set_uj(right_data(), i, GMP_RNDU);
Chris@16 107 return *this;
Chris@16 108 }
Chris@16 109 mpfi_float_imp& operator = (long long i)
Chris@16 110 {
Chris@16 111 if(m_data[0].left._mpfr_d == 0)
Chris@16 112 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 113 mpfr_set_sj(left_data(), i, GMP_RNDD);
Chris@16 114 mpfr_set_sj(right_data(), i, GMP_RNDU);
Chris@16 115 return *this;
Chris@16 116 }
Chris@16 117 #else
Chris@16 118 mpfi_float_imp& operator = (unsigned long long i)
Chris@16 119 {
Chris@16 120 if(m_data[0].left._mpfr_d == 0)
Chris@16 121 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 122 unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
Chris@16 123 unsigned shift = 0;
Chris@16 124 mpfi_t t;
Chris@16 125 mpfi_init2(t, (std::max)(static_cast<unsigned>(std::numeric_limits<unsigned long long>::digits), static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10))));
Chris@16 126 mpfi_set_ui(m_data, 0);
Chris@16 127 while(i)
Chris@16 128 {
Chris@16 129 mpfi_set_ui(t, static_cast<unsigned>(i & mask));
Chris@16 130 if(shift)
Chris@16 131 mpfi_mul_2exp(t, t, shift);
Chris@16 132 mpfi_add(m_data, m_data, t);
Chris@16 133 shift += std::numeric_limits<unsigned>::digits;
Chris@16 134 i >>= std::numeric_limits<unsigned>::digits;
Chris@16 135 }
Chris@16 136 mpfi_clear(t);
Chris@16 137 return *this;
Chris@16 138 }
Chris@16 139 mpfi_float_imp& operator = (long long i)
Chris@16 140 {
Chris@16 141 if(m_data[0].left._mpfr_d == 0)
Chris@16 142 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 143 bool neg = i < 0;
Chris@101 144 *this = boost::multiprecision::detail::unsigned_abs(i);
Chris@16 145 if(neg)
Chris@16 146 mpfi_neg(m_data, m_data);
Chris@16 147 return *this;
Chris@16 148 }
Chris@16 149 #endif
Chris@16 150 mpfi_float_imp& operator = (unsigned long i)
Chris@16 151 {
Chris@16 152 if(m_data[0].left._mpfr_d == 0)
Chris@16 153 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 154 mpfi_set_ui(m_data, i);
Chris@16 155 return *this;
Chris@16 156 }
Chris@16 157 mpfi_float_imp& operator = (long i)
Chris@16 158 {
Chris@16 159 if(m_data[0].left._mpfr_d == 0)
Chris@16 160 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 161 mpfi_set_si(m_data, i);
Chris@16 162 return *this;
Chris@16 163 }
Chris@16 164 mpfi_float_imp& operator = (double d)
Chris@16 165 {
Chris@16 166 if(m_data[0].left._mpfr_d == 0)
Chris@16 167 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 168 mpfi_set_d(m_data, d);
Chris@16 169 return *this;
Chris@16 170 }
Chris@16 171 mpfi_float_imp& operator = (long double a)
Chris@16 172 {
Chris@16 173 if(m_data[0].left._mpfr_d == 0)
Chris@16 174 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 175 mpfr_set_ld(left_data(), a, GMP_RNDD);
Chris@16 176 mpfr_set_ld(right_data(), a, GMP_RNDU);
Chris@16 177 return *this;
Chris@16 178 }
Chris@16 179 mpfi_float_imp& operator = (const char* s)
Chris@16 180 {
Chris@101 181 using default_ops::eval_fpclassify;
Chris@101 182
Chris@16 183 if(m_data[0].left._mpfr_d == 0)
Chris@16 184 mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
Chris@16 185
Chris@16 186 if(s && (*s == '{'))
Chris@16 187 {
Chris@16 188 mpfr_float_backend<digits10> a, b;
Chris@16 189 std::string part;
Chris@16 190 const char* p = ++s;
Chris@16 191 while(*p && (*p != ',') && (*p != '}'))
Chris@16 192 ++p;
Chris@16 193 part.assign(s + 1, p);
Chris@16 194 a = part.c_str();
Chris@16 195 s = p;
Chris@16 196 if(*p && (*p != '}'))
Chris@16 197 {
Chris@16 198 ++p;
Chris@16 199 while(*p && (*p != ',') && (*p != '}'))
Chris@16 200 ++p;
Chris@16 201 part.assign(s + 1, p);
Chris@16 202 }
Chris@16 203 else
Chris@16 204 part.erase();
Chris@16 205 b = part.c_str();
Chris@16 206
Chris@101 207 if(eval_fpclassify(a) == (int)FP_NAN)
Chris@101 208 {
Chris@101 209 mpfi_set_fr(this->data(), a.data());
Chris@101 210 }
Chris@101 211 else if(eval_fpclassify(b) == (int)FP_NAN)
Chris@101 212 {
Chris@101 213 mpfi_set_fr(this->data(), b.data());
Chris@101 214 }
Chris@101 215 else
Chris@101 216 {
Chris@101 217 if(a.compare(b) > 0)
Chris@101 218 {
Chris@101 219 BOOST_THROW_EXCEPTION(std::runtime_error("Attempt to create interval with invalid range (start is greater than end)."));
Chris@101 220 }
Chris@101 221 mpfi_interv_fr(m_data, a.data(), b.data());
Chris@101 222 }
Chris@16 223 }
Chris@16 224 else if(mpfi_set_str(m_data, s, 10) != 0)
Chris@16 225 {
Chris@16 226 BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
Chris@16 227 }
Chris@16 228 return *this;
Chris@16 229 }
Chris@16 230 void swap(mpfi_float_imp& o) BOOST_NOEXCEPT
Chris@16 231 {
Chris@16 232 mpfi_swap(m_data, o.m_data);
Chris@16 233 }
Chris@16 234 std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
Chris@16 235 {
Chris@16 236 BOOST_ASSERT(m_data[0].left._mpfr_d);
Chris@16 237
Chris@16 238 mpfr_float_backend<digits10> a, b;
Chris@16 239
Chris@16 240 mpfi_get_left(a.data(), m_data);
Chris@16 241 mpfi_get_right(b.data(), m_data);
Chris@16 242
Chris@16 243 if(a.compare(b) == 0)
Chris@16 244 return a.str(digits, f);
Chris@16 245
Chris@16 246 return "{" + a.str(digits, f) + "," + b.str(digits, f) + "}";
Chris@16 247 }
Chris@16 248 ~mpfi_float_imp() BOOST_NOEXCEPT
Chris@16 249 {
Chris@16 250 if(m_data[0].left._mpfr_d)
Chris@16 251 mpfi_clear(m_data);
Chris@16 252 }
Chris@16 253 void negate() BOOST_NOEXCEPT
Chris@16 254 {
Chris@16 255 BOOST_ASSERT(m_data[0].left._mpfr_d);
Chris@16 256 mpfi_neg(m_data, m_data);
Chris@16 257 }
Chris@16 258 int compare(const mpfi_float_imp& o)const BOOST_NOEXCEPT
Chris@16 259 {
Chris@16 260 BOOST_ASSERT(m_data[0].left._mpfr_d && o.m_data[0].left._mpfr_d);
Chris@16 261 if(mpfr_cmp(right_data(), o.left_data()) < 0)
Chris@16 262 return -1;
Chris@16 263 if(mpfr_cmp(left_data(), o.right_data()) > 0)
Chris@16 264 return 1;
Chris@16 265 if((mpfr_cmp(left_data(), o.left_data()) == 0) && (mpfr_cmp(right_data(), o.right_data()) == 0))
Chris@16 266 return 0;
Chris@16 267 BOOST_THROW_EXCEPTION(interval_error("Ambiguous comparison between two values."));
Chris@16 268 return 0;
Chris@16 269 }
Chris@16 270 template <class V>
Chris@16 271 int compare(V v)const BOOST_NOEXCEPT
Chris@16 272 {
Chris@16 273 mpfi_float_imp d;
Chris@16 274 d = v;
Chris@16 275 return compare(d);
Chris@16 276 }
Chris@16 277 mpfi_t& data() BOOST_NOEXCEPT
Chris@16 278 {
Chris@16 279 BOOST_ASSERT(m_data[0].left._mpfr_d);
Chris@16 280 return m_data;
Chris@16 281 }
Chris@16 282 const mpfi_t& data()const BOOST_NOEXCEPT
Chris@16 283 {
Chris@16 284 BOOST_ASSERT(m_data[0].left._mpfr_d);
Chris@16 285 return m_data;
Chris@16 286 }
Chris@16 287 mpfr_ptr left_data() BOOST_NOEXCEPT
Chris@16 288 {
Chris@16 289 BOOST_ASSERT(m_data[0].left._mpfr_d);
Chris@16 290 return &(m_data[0].left);
Chris@16 291 }
Chris@16 292 mpfr_srcptr left_data()const BOOST_NOEXCEPT
Chris@16 293 {
Chris@16 294 BOOST_ASSERT(m_data[0].left._mpfr_d);
Chris@16 295 return &(m_data[0].left);
Chris@16 296 }
Chris@16 297 mpfr_ptr right_data() BOOST_NOEXCEPT
Chris@16 298 {
Chris@16 299 BOOST_ASSERT(m_data[0].left._mpfr_d);
Chris@16 300 return &(m_data[0].right);
Chris@16 301 }
Chris@16 302 mpfr_srcptr right_data()const BOOST_NOEXCEPT
Chris@16 303 {
Chris@16 304 BOOST_ASSERT(m_data[0].left._mpfr_d);
Chris@16 305 return &(m_data[0].right);
Chris@16 306 }
Chris@16 307 protected:
Chris@16 308 mpfi_t m_data;
Chris@16 309 static unsigned& get_default_precision() BOOST_NOEXCEPT
Chris@16 310 {
Chris@16 311 static unsigned val = 50;
Chris@16 312 return val;
Chris@16 313 }
Chris@16 314 };
Chris@16 315
Chris@16 316 } // namespace detail
Chris@16 317
Chris@16 318 template <unsigned digits10>
Chris@16 319 struct mpfi_float_backend : public detail::mpfi_float_imp<digits10>
Chris@16 320 {
Chris@16 321 mpfi_float_backend() : detail::mpfi_float_imp<digits10>() {}
Chris@16 322 mpfi_float_backend(const mpfi_float_backend& o) : detail::mpfi_float_imp<digits10>(o) {}
Chris@16 323 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@16 324 mpfi_float_backend(mpfi_float_backend&& o) : detail::mpfi_float_imp<digits10>(static_cast<detail::mpfi_float_imp<digits10>&&>(o)) {}
Chris@16 325 #endif
Chris@16 326 template <unsigned D>
Chris@16 327 mpfi_float_backend(const mpfi_float_backend<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
Chris@16 328 : detail::mpfi_float_imp<digits10>()
Chris@16 329 {
Chris@16 330 mpfi_set(this->m_data, val.data());
Chris@16 331 }
Chris@16 332 template <unsigned D>
Chris@16 333 explicit mpfi_float_backend(const mpfi_float_backend<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
Chris@16 334 : detail::mpfi_float_imp<digits10>()
Chris@16 335 {
Chris@16 336 mpfi_set(this->m_data, val.data());
Chris@16 337 }
Chris@16 338 mpfi_float_backend(const mpfi_t val)
Chris@16 339 : detail::mpfi_float_imp<digits10>()
Chris@16 340 {
Chris@16 341 mpfi_set(this->m_data, val);
Chris@16 342 }
Chris@16 343 mpfi_float_backend& operator=(const mpfi_float_backend& o)
Chris@16 344 {
Chris@16 345 *static_cast<detail::mpfi_float_imp<digits10>*>(this) = static_cast<detail::mpfi_float_imp<digits10> const&>(o);
Chris@16 346 return *this;
Chris@16 347 }
Chris@16 348 template <unsigned D>
Chris@16 349 mpfi_float_backend(const mpfr_float_backend<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
Chris@16 350 : detail::mpfi_float_imp<digits10>()
Chris@16 351 {
Chris@16 352 mpfi_set_fr(this->m_data, val.data());
Chris@16 353 }
Chris@16 354 template <unsigned D>
Chris@16 355 mpfi_float_backend& operator=(const mpfr_float_backend<D>& val)
Chris@16 356 {
Chris@16 357 mpfi_set_fr(this->m_data, val.data());
Chris@16 358 return *this;
Chris@16 359 }
Chris@16 360 template <unsigned D>
Chris@16 361 explicit mpfi_float_backend(const mpfr_float_backend<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
Chris@16 362 : detail::mpfi_float_imp<digits10>()
Chris@16 363 {
Chris@16 364 mpfi_set_fr(this->m_data, val.data());
Chris@16 365 }
Chris@16 366 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@16 367 mpfi_float_backend& operator=(mpfi_float_backend&& o) BOOST_NOEXCEPT
Chris@16 368 {
Chris@16 369 *static_cast<detail::mpfi_float_imp<digits10>*>(this) = static_cast<detail::mpfi_float_imp<digits10>&&>(o);
Chris@16 370 return *this;
Chris@16 371 }
Chris@16 372 #endif
Chris@16 373 template <class V>
Chris@16 374 mpfi_float_backend& operator=(const V& v)
Chris@16 375 {
Chris@16 376 *static_cast<detail::mpfi_float_imp<digits10>*>(this) = v;
Chris@16 377 return *this;
Chris@16 378 }
Chris@16 379 mpfi_float_backend& operator=(const mpfi_t val)
Chris@16 380 {
Chris@16 381 mpfi_set(this->m_data, val);
Chris@16 382 return *this;
Chris@16 383 }
Chris@16 384 // We don't change our precision here, this is a fixed precision type:
Chris@16 385 template <unsigned D>
Chris@16 386 mpfi_float_backend& operator=(const mpfi_float_backend<D>& val)
Chris@16 387 {
Chris@16 388 mpfi_set(this->m_data, val.data());
Chris@16 389 return *this;
Chris@16 390 }
Chris@16 391 };
Chris@16 392
Chris@16 393 template <>
Chris@16 394 struct mpfi_float_backend<0> : public detail::mpfi_float_imp<0>
Chris@16 395 {
Chris@16 396 mpfi_float_backend() : detail::mpfi_float_imp<0>() {}
Chris@16 397 mpfi_float_backend(const mpfi_t val)
Chris@16 398 : detail::mpfi_float_imp<0>(mpfi_get_prec(val))
Chris@16 399 {
Chris@16 400 mpfi_set(this->m_data, val);
Chris@16 401 }
Chris@16 402 mpfi_float_backend(const mpfi_float_backend& o) : detail::mpfi_float_imp<0>(o) {}
Chris@16 403 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@16 404 mpfi_float_backend(mpfi_float_backend&& o) BOOST_NOEXCEPT : detail::mpfi_float_imp<0>(static_cast<detail::mpfi_float_imp<0>&&>(o)) {}
Chris@16 405 #endif
Chris@16 406 mpfi_float_backend(const mpfi_float_backend& o, unsigned digits10)
Chris@16 407 : detail::mpfi_float_imp<0>(digits10)
Chris@16 408 {
Chris@16 409 *this = o;
Chris@16 410 }
Chris@16 411 template <unsigned D>
Chris@16 412 mpfi_float_backend(const mpfi_float_backend<D>& val)
Chris@16 413 : detail::mpfi_float_imp<0>(mpfi_get_prec(val.data()))
Chris@16 414 {
Chris@16 415 mpfi_set(this->m_data, val.data());
Chris@16 416 }
Chris@16 417 mpfi_float_backend& operator=(const mpfi_float_backend& o)
Chris@16 418 {
Chris@16 419 mpfi_set_prec(this->m_data, mpfi_get_prec(o.data()));
Chris@16 420 mpfi_set(this->m_data, o.data());
Chris@16 421 return *this;
Chris@16 422 }
Chris@16 423 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
Chris@16 424 mpfi_float_backend& operator=(mpfi_float_backend&& o) BOOST_NOEXCEPT
Chris@16 425 {
Chris@16 426 *static_cast<detail::mpfi_float_imp<0>*>(this) = static_cast<detail::mpfi_float_imp<0> &&>(o);
Chris@16 427 return *this;
Chris@16 428 }
Chris@16 429 #endif
Chris@16 430 template <class V>
Chris@16 431 mpfi_float_backend& operator=(const V& v)
Chris@16 432 {
Chris@16 433 *static_cast<detail::mpfi_float_imp<0>*>(this) = v;
Chris@16 434 return *this;
Chris@16 435 }
Chris@16 436 mpfi_float_backend& operator=(const mpfi_t val)
Chris@16 437 {
Chris@16 438 mpfi_set_prec(this->m_data, mpfi_get_prec(val));
Chris@16 439 mpfi_set(this->m_data, val);
Chris@16 440 return *this;
Chris@16 441 }
Chris@16 442 template <unsigned D>
Chris@16 443 mpfi_float_backend& operator=(const mpfi_float_backend<D>& val)
Chris@16 444 {
Chris@16 445 mpfi_set_prec(this->m_data, mpfi_get_prec(val.data()));
Chris@16 446 mpfi_set(this->m_data, val.data());
Chris@16 447 return *this;
Chris@16 448 }
Chris@16 449 static unsigned default_precision() BOOST_NOEXCEPT
Chris@16 450 {
Chris@16 451 return get_default_precision();
Chris@16 452 }
Chris@16 453 static void default_precision(unsigned v) BOOST_NOEXCEPT
Chris@16 454 {
Chris@16 455 get_default_precision() = v;
Chris@16 456 }
Chris@16 457 unsigned precision()const BOOST_NOEXCEPT
Chris@16 458 {
Chris@16 459 return multiprecision::detail::digits2_2_10(mpfi_get_prec(this->m_data));
Chris@16 460 }
Chris@16 461 void precision(unsigned digits10) BOOST_NOEXCEPT
Chris@16 462 {
Chris@16 463 mpfi_set_prec(this->m_data, multiprecision::detail::digits2_2_10((digits10)));
Chris@16 464 }
Chris@16 465 };
Chris@16 466
Chris@16 467 template <unsigned digits10, class T>
Chris@16 468 inline typename enable_if<is_arithmetic<T>, bool>::type eval_eq(const mpfi_float_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
Chris@16 469 {
Chris@16 470 return a.compare(b) == 0;
Chris@16 471 }
Chris@16 472 template <unsigned digits10, class T>
Chris@16 473 inline typename enable_if<is_arithmetic<T>, bool>::type eval_lt(const mpfi_float_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
Chris@16 474 {
Chris@16 475 return a.compare(b) < 0;
Chris@16 476 }
Chris@16 477 template <unsigned digits10, class T>
Chris@16 478 inline typename enable_if<is_arithmetic<T>, bool>::type eval_gt(const mpfi_float_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
Chris@16 479 {
Chris@16 480 return a.compare(b) > 0;
Chris@16 481 }
Chris@16 482
Chris@16 483 template <unsigned D1, unsigned D2>
Chris@16 484 inline void eval_add(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
Chris@16 485 {
Chris@16 486 mpfi_add(result.data(), result.data(), o.data());
Chris@16 487 }
Chris@16 488 template <unsigned D1, unsigned D2>
Chris@16 489 inline void eval_subtract(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
Chris@16 490 {
Chris@16 491 mpfi_sub(result.data(), result.data(), o.data());
Chris@16 492 }
Chris@16 493 template <unsigned D1, unsigned D2>
Chris@16 494 inline void eval_multiply(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
Chris@16 495 {
Chris@16 496 if((void*)&result == (void*)&o)
Chris@16 497 mpfi_sqr(result.data(), o.data());
Chris@16 498 else
Chris@16 499 mpfi_mul(result.data(), result.data(), o.data());
Chris@16 500 }
Chris@16 501 template <unsigned D1, unsigned D2>
Chris@16 502 inline void eval_divide(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
Chris@16 503 {
Chris@16 504 mpfi_div(result.data(), result.data(), o.data());
Chris@16 505 }
Chris@16 506 template <unsigned digits10>
Chris@16 507 inline void eval_add(mpfi_float_backend<digits10>& result, unsigned long i)
Chris@16 508 {
Chris@16 509 mpfi_add_ui(result.data(), result.data(), i);
Chris@16 510 }
Chris@16 511 template <unsigned digits10>
Chris@16 512 inline void eval_subtract(mpfi_float_backend<digits10>& result, unsigned long i)
Chris@16 513 {
Chris@16 514 mpfi_sub_ui(result.data(), result.data(), i);
Chris@16 515 }
Chris@16 516 template <unsigned digits10>
Chris@16 517 inline void eval_multiply(mpfi_float_backend<digits10>& result, unsigned long i)
Chris@16 518 {
Chris@16 519 mpfi_mul_ui(result.data(), result.data(), i);
Chris@16 520 }
Chris@16 521 template <unsigned digits10>
Chris@16 522 inline void eval_divide(mpfi_float_backend<digits10>& result, unsigned long i)
Chris@16 523 {
Chris@16 524 mpfi_div_ui(result.data(), result.data(), i);
Chris@16 525 }
Chris@16 526 template <unsigned digits10>
Chris@16 527 inline void eval_add(mpfi_float_backend<digits10>& result, long i)
Chris@16 528 {
Chris@16 529 if(i > 0)
Chris@16 530 mpfi_add_ui(result.data(), result.data(), i);
Chris@16 531 else
Chris@101 532 mpfi_sub_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
Chris@16 533 }
Chris@16 534 template <unsigned digits10>
Chris@16 535 inline void eval_subtract(mpfi_float_backend<digits10>& result, long i)
Chris@16 536 {
Chris@16 537 if(i > 0)
Chris@16 538 mpfi_sub_ui(result.data(), result.data(), i);
Chris@16 539 else
Chris@101 540 mpfi_add_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
Chris@16 541 }
Chris@16 542 template <unsigned digits10>
Chris@16 543 inline void eval_multiply(mpfi_float_backend<digits10>& result, long i)
Chris@16 544 {
Chris@101 545 mpfi_mul_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
Chris@16 546 if(i < 0)
Chris@16 547 mpfi_neg(result.data(), result.data());
Chris@16 548 }
Chris@16 549 template <unsigned digits10>
Chris@16 550 inline void eval_divide(mpfi_float_backend<digits10>& result, long i)
Chris@16 551 {
Chris@101 552 mpfi_div_ui(result.data(), result.data(), boost::multiprecision::detail::unsigned_abs(i));
Chris@16 553 if(i < 0)
Chris@16 554 mpfi_neg(result.data(), result.data());
Chris@16 555 }
Chris@16 556 //
Chris@16 557 // Specialised 3 arg versions of the basic operators:
Chris@16 558 //
Chris@16 559 template <unsigned D1, unsigned D2, unsigned D3>
Chris@16 560 inline void eval_add(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
Chris@16 561 {
Chris@16 562 mpfi_add(a.data(), x.data(), y.data());
Chris@16 563 }
Chris@16 564 template <unsigned D1, unsigned D2>
Chris@16 565 inline void eval_add(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
Chris@16 566 {
Chris@16 567 mpfi_add_ui(a.data(), x.data(), y);
Chris@16 568 }
Chris@16 569 template <unsigned D1, unsigned D2>
Chris@16 570 inline void eval_add(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
Chris@16 571 {
Chris@16 572 if(y < 0)
Chris@101 573 mpfi_sub_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
Chris@16 574 else
Chris@16 575 mpfi_add_ui(a.data(), x.data(), y);
Chris@16 576 }
Chris@16 577 template <unsigned D1, unsigned D2>
Chris@16 578 inline void eval_add(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
Chris@16 579 {
Chris@16 580 mpfi_add_ui(a.data(), y.data(), x);
Chris@16 581 }
Chris@16 582 template <unsigned D1, unsigned D2>
Chris@16 583 inline void eval_add(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
Chris@16 584 {
Chris@16 585 if(x < 0)
Chris@16 586 {
Chris@101 587 mpfi_ui_sub(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data());
Chris@16 588 mpfi_neg(a.data(), a.data());
Chris@16 589 }
Chris@16 590 else
Chris@16 591 mpfi_add_ui(a.data(), y.data(), x);
Chris@16 592 }
Chris@16 593 template <unsigned D1, unsigned D2, unsigned D3>
Chris@16 594 inline void eval_subtract(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
Chris@16 595 {
Chris@16 596 mpfi_sub(a.data(), x.data(), y.data());
Chris@16 597 }
Chris@16 598 template <unsigned D1, unsigned D2>
Chris@16 599 inline void eval_subtract(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
Chris@16 600 {
Chris@16 601 mpfi_sub_ui(a.data(), x.data(), y);
Chris@16 602 }
Chris@16 603 template <unsigned D1, unsigned D2>
Chris@16 604 inline void eval_subtract(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
Chris@16 605 {
Chris@16 606 if(y < 0)
Chris@101 607 mpfi_add_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
Chris@16 608 else
Chris@16 609 mpfi_sub_ui(a.data(), x.data(), y);
Chris@16 610 }
Chris@16 611 template <unsigned D1, unsigned D2>
Chris@16 612 inline void eval_subtract(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
Chris@16 613 {
Chris@16 614 mpfi_ui_sub(a.data(), x, y.data());
Chris@16 615 }
Chris@16 616 template <unsigned D1, unsigned D2>
Chris@16 617 inline void eval_subtract(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
Chris@16 618 {
Chris@16 619 if(x < 0)
Chris@16 620 {
Chris@101 621 mpfi_add_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x));
Chris@16 622 mpfi_neg(a.data(), a.data());
Chris@16 623 }
Chris@16 624 else
Chris@16 625 mpfi_ui_sub(a.data(), x, y.data());
Chris@16 626 }
Chris@16 627
Chris@16 628 template <unsigned D1, unsigned D2, unsigned D3>
Chris@16 629 inline void eval_multiply(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
Chris@16 630 {
Chris@16 631 if((void*)&x == (void*)&y)
Chris@16 632 mpfi_sqr(a.data(), x.data());
Chris@16 633 else
Chris@16 634 mpfi_mul(a.data(), x.data(), y.data());
Chris@16 635 }
Chris@16 636 template <unsigned D1, unsigned D2>
Chris@16 637 inline void eval_multiply(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
Chris@16 638 {
Chris@16 639 mpfi_mul_ui(a.data(), x.data(), y);
Chris@16 640 }
Chris@16 641 template <unsigned D1, unsigned D2>
Chris@16 642 inline void eval_multiply(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
Chris@16 643 {
Chris@16 644 if(y < 0)
Chris@16 645 {
Chris@101 646 mpfi_mul_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
Chris@16 647 a.negate();
Chris@16 648 }
Chris@16 649 else
Chris@16 650 mpfi_mul_ui(a.data(), x.data(), y);
Chris@16 651 }
Chris@16 652 template <unsigned D1, unsigned D2>
Chris@16 653 inline void eval_multiply(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
Chris@16 654 {
Chris@16 655 mpfi_mul_ui(a.data(), y.data(), x);
Chris@16 656 }
Chris@16 657 template <unsigned D1, unsigned D2>
Chris@16 658 inline void eval_multiply(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
Chris@16 659 {
Chris@16 660 if(x < 0)
Chris@16 661 {
Chris@101 662 mpfi_mul_ui(a.data(), y.data(), boost::multiprecision::detail::unsigned_abs(x));
Chris@16 663 mpfi_neg(a.data(), a.data());
Chris@16 664 }
Chris@16 665 else
Chris@16 666 mpfi_mul_ui(a.data(), y.data(), x);
Chris@16 667 }
Chris@16 668
Chris@16 669 template <unsigned D1, unsigned D2, unsigned D3>
Chris@16 670 inline void eval_divide(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
Chris@16 671 {
Chris@16 672 mpfi_div(a.data(), x.data(), y.data());
Chris@16 673 }
Chris@16 674 template <unsigned D1, unsigned D2>
Chris@16 675 inline void eval_divide(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
Chris@16 676 {
Chris@16 677 mpfi_div_ui(a.data(), x.data(), y);
Chris@16 678 }
Chris@16 679 template <unsigned D1, unsigned D2>
Chris@16 680 inline void eval_divide(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
Chris@16 681 {
Chris@16 682 if(y < 0)
Chris@16 683 {
Chris@101 684 mpfi_div_ui(a.data(), x.data(), boost::multiprecision::detail::unsigned_abs(y));
Chris@16 685 a.negate();
Chris@16 686 }
Chris@16 687 else
Chris@16 688 mpfi_div_ui(a.data(), x.data(), y);
Chris@16 689 }
Chris@16 690 template <unsigned D1, unsigned D2>
Chris@16 691 inline void eval_divide(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
Chris@16 692 {
Chris@16 693 mpfi_ui_div(a.data(), x, y.data());
Chris@16 694 }
Chris@16 695 template <unsigned D1, unsigned D2>
Chris@16 696 inline void eval_divide(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
Chris@16 697 {
Chris@16 698 if(x < 0)
Chris@16 699 {
Chris@101 700 mpfi_ui_div(a.data(), boost::multiprecision::detail::unsigned_abs(x), y.data());
Chris@16 701 mpfi_neg(a.data(), a.data());
Chris@16 702 }
Chris@16 703 else
Chris@16 704 mpfi_ui_div(a.data(), x, y.data());
Chris@16 705 }
Chris@16 706
Chris@16 707 template <unsigned digits10>
Chris@16 708 inline bool eval_is_zero(const mpfi_float_backend<digits10>& val) BOOST_NOEXCEPT
Chris@16 709 {
Chris@16 710 return 0 != mpfi_is_zero(val.data());
Chris@16 711 }
Chris@16 712 template <unsigned digits10>
Chris@16 713 inline int eval_get_sign(const mpfi_float_backend<digits10>& val)
Chris@16 714 {
Chris@16 715 return detail::mpfi_sgn(val.data());
Chris@16 716 }
Chris@16 717
Chris@16 718 template <unsigned digits10>
Chris@16 719 inline void eval_convert_to(unsigned long* result, const mpfi_float_backend<digits10>& val)
Chris@16 720 {
Chris@16 721 mpfr_float_backend<digits10> t;
Chris@16 722 mpfi_mid(t.data(), val.data());
Chris@16 723 eval_convert_to(result, t);
Chris@16 724 }
Chris@16 725 template <unsigned digits10>
Chris@16 726 inline void eval_convert_to(long* result, const mpfi_float_backend<digits10>& val)
Chris@16 727 {
Chris@16 728 mpfr_float_backend<digits10> t;
Chris@16 729 mpfi_mid(t.data(), val.data());
Chris@16 730 eval_convert_to(result, t);
Chris@16 731 }
Chris@16 732 #ifdef _MPFR_H_HAVE_INTMAX_T
Chris@16 733 template <unsigned digits10>
Chris@16 734 inline void eval_convert_to(unsigned long long* result, const mpfi_float_backend<digits10>& val)
Chris@16 735 {
Chris@16 736 mpfr_float_backend<digits10> t;
Chris@16 737 mpfi_mid(t.data(), val.data());
Chris@16 738 eval_convert_to(result, t);
Chris@16 739 }
Chris@16 740 template <unsigned digits10>
Chris@16 741 inline void eval_convert_to(long long* result, const mpfi_float_backend<digits10>& val)
Chris@16 742 {
Chris@16 743 mpfr_float_backend<digits10> t;
Chris@16 744 mpfi_mid(t.data(), val.data());
Chris@16 745 eval_convert_to(result, t);
Chris@16 746 }
Chris@16 747 #endif
Chris@16 748 template <unsigned digits10>
Chris@16 749 inline void eval_convert_to(double* result, const mpfi_float_backend<digits10>& val) BOOST_NOEXCEPT
Chris@16 750 {
Chris@16 751 *result = mpfi_get_d(val.data());
Chris@16 752 }
Chris@16 753 template <unsigned digits10>
Chris@16 754 inline void eval_convert_to(long double* result, const mpfi_float_backend<digits10>& val) BOOST_NOEXCEPT
Chris@16 755 {
Chris@16 756 mpfr_float_backend<digits10> t;
Chris@16 757 mpfi_mid(t.data(), val.data());
Chris@16 758 eval_convert_to(result, t);
Chris@16 759 }
Chris@16 760
Chris@16 761 template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
Chris@16 762 inline void assign_components(mpfi_float_backend<D1>& result, const mpfr_float_backend<D2, AllocationType>& a, const mpfr_float_backend<D2, AllocationType>& b)
Chris@16 763 {
Chris@101 764 using default_ops::eval_fpclassify;
Chris@101 765 if(eval_fpclassify(a) == (int)FP_NAN)
Chris@101 766 {
Chris@101 767 mpfi_set_fr(result.data(), a.data());
Chris@101 768 }
Chris@101 769 else if(eval_fpclassify(b) == (int)FP_NAN)
Chris@101 770 {
Chris@101 771 mpfi_set_fr(result.data(), b.data());
Chris@101 772 }
Chris@101 773 else
Chris@101 774 {
Chris@101 775 if(a.compare(b) > 0)
Chris@101 776 {
Chris@101 777 BOOST_THROW_EXCEPTION(std::runtime_error("Attempt to create interval with invalid range (start is greater than end)."));
Chris@101 778 }
Chris@101 779 mpfi_interv_fr(result.data(), a.data(), b.data());
Chris@101 780 }
Chris@16 781 }
Chris@16 782
Chris@16 783 template <unsigned Digits10, class V>
Chris@16 784 inline typename enable_if_c<is_convertible<V, number<mpfr_float_backend<Digits10, allocate_dynamic>, et_on> >::value >::type
Chris@16 785 assign_components(mpfi_float_backend<Digits10>& result, const V& a, const V& b)
Chris@16 786 {
Chris@16 787 number<mpfr_float_backend<Digits10, allocate_dynamic>, et_on> x(a), y(b);
Chris@16 788 assign_components(result, x.backend(), y.backend());
Chris@16 789 }
Chris@16 790
Chris@16 791 //
Chris@16 792 // Native non-member operations:
Chris@16 793 //
Chris@16 794 template <unsigned Digits10>
Chris@16 795 inline void eval_sqrt(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
Chris@16 796 {
Chris@16 797 mpfi_sqrt(result.data(), val.data());
Chris@16 798 }
Chris@16 799
Chris@16 800 template <unsigned Digits10>
Chris@16 801 inline void eval_abs(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
Chris@16 802 {
Chris@16 803 mpfi_abs(result.data(), val.data());
Chris@16 804 }
Chris@16 805
Chris@16 806 template <unsigned Digits10>
Chris@16 807 inline void eval_fabs(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
Chris@16 808 {
Chris@16 809 mpfi_abs(result.data(), val.data());
Chris@16 810 }
Chris@16 811 template <unsigned Digits10>
Chris@16 812 inline void eval_ceil(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
Chris@16 813 {
Chris@16 814 mpfr_float_backend<Digits10> a, b;
Chris@16 815 mpfr_set(a.data(), val.left_data(), GMP_RNDN);
Chris@16 816 mpfr_set(b.data(), val.right_data(), GMP_RNDN);
Chris@16 817 eval_ceil(a, a);
Chris@16 818 eval_ceil(b, b);
Chris@16 819 if(a.compare(b) != 0)
Chris@16 820 {
Chris@16 821 BOOST_THROW_EXCEPTION(interval_error("Attempt to take the ceil of a value that straddles an integer boundary."));
Chris@16 822 }
Chris@16 823 mpfi_set_fr(result.data(), a.data());
Chris@16 824 }
Chris@16 825 template <unsigned Digits10>
Chris@16 826 inline void eval_floor(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
Chris@16 827 {
Chris@16 828 mpfr_float_backend<Digits10> a, b;
Chris@16 829 mpfr_set(a.data(), val.left_data(), GMP_RNDN);
Chris@16 830 mpfr_set(b.data(), val.right_data(), GMP_RNDN);
Chris@16 831 eval_floor(a, a);
Chris@16 832 eval_floor(b, b);
Chris@16 833 if(a.compare(b) != 0)
Chris@16 834 {
Chris@16 835 BOOST_THROW_EXCEPTION(interval_error("Attempt to take the floor of a value that straddles an integer boundary."));
Chris@16 836 }
Chris@16 837 mpfi_set_fr(result.data(), a.data());
Chris@16 838 }
Chris@16 839 template <unsigned Digits10>
Chris@16 840 inline void eval_ldexp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val, long e)
Chris@16 841 {
Chris@16 842 if(e > 0)
Chris@16 843 mpfi_mul_2exp(result.data(), val.data(), e);
Chris@16 844 else if(e < 0)
Chris@16 845 mpfi_div_2exp(result.data(), val.data(), -e);
Chris@16 846 else
Chris@16 847 result = val;
Chris@16 848 }
Chris@16 849 template <unsigned Digits10>
Chris@16 850 inline void eval_frexp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val, int* e)
Chris@16 851 {
Chris@16 852 mpfr_float_backend<Digits10> t, rt;
Chris@16 853 mpfi_mid(t.data(), val.data());
Chris@16 854 eval_frexp(rt, t, e);
Chris@16 855 eval_ldexp(result, val, -*e);
Chris@16 856 }
Chris@16 857 template <unsigned Digits10>
Chris@16 858 inline void eval_frexp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val, long* e)
Chris@16 859 {
Chris@16 860 mpfr_float_backend<Digits10> t, rt;
Chris@16 861 mpfi_mid(t.data(), val.data());
Chris@16 862 eval_frexp(rt, t, e);
Chris@16 863 eval_ldexp(result, val, -*e);
Chris@16 864 }
Chris@16 865
Chris@16 866 template <unsigned Digits10>
Chris@16 867 inline int eval_fpclassify(const mpfi_float_backend<Digits10>& val) BOOST_NOEXCEPT
Chris@16 868 {
Chris@16 869 return mpfi_inf_p(val.data()) ? FP_INFINITE : mpfi_nan_p(val.data()) ? FP_NAN : mpfi_is_zero(val.data()) ? FP_ZERO : FP_NORMAL;
Chris@16 870 }
Chris@16 871
Chris@16 872 template <unsigned Digits10>
Chris@16 873 inline void eval_pow(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& b, const mpfi_float_backend<Digits10>& e)
Chris@16 874 {
Chris@16 875 typedef typename boost::multiprecision::detail::canonical<unsigned, mpfi_float_backend<Digits10> >::type ui_type;
Chris@16 876 using default_ops::eval_get_sign;
Chris@16 877 int s = eval_get_sign(b);
Chris@16 878 if(s == 0)
Chris@16 879 {
Chris@16 880 if(eval_get_sign(e) == 0)
Chris@16 881 {
Chris@16 882 result = ui_type(1);
Chris@16 883 }
Chris@16 884 else
Chris@16 885 {
Chris@16 886 result = ui_type(0);
Chris@16 887 }
Chris@16 888 return;
Chris@16 889 }
Chris@16 890 if(s < 0)
Chris@16 891 {
Chris@16 892 if(eval_get_sign(e) < 0)
Chris@16 893 {
Chris@16 894 mpfi_float_backend<Digits10> t1, t2;
Chris@16 895 t1 = e;
Chris@16 896 t1.negate();
Chris@16 897 eval_pow(t2, b, t1);
Chris@16 898 t1 = ui_type(1);
Chris@16 899 eval_divide(result, t1, t2);
Chris@16 900 return;
Chris@16 901 }
Chris@16 902 typename boost::multiprecision::detail::canonical<boost::uintmax_t, mpfi_float_backend<Digits10> >::type an;
Chris@16 903 try
Chris@16 904 {
Chris@16 905 using default_ops::eval_convert_to;
Chris@16 906 eval_convert_to(&an, e);
Chris@16 907 if(e.compare(an) == 0)
Chris@16 908 {
Chris@16 909 mpfi_float_backend<Digits10> pb(b);
Chris@16 910 pb.negate();
Chris@16 911 eval_pow(result, pb, e);
Chris@16 912 if(an & 1u)
Chris@16 913 result.negate();
Chris@16 914 return;
Chris@16 915 }
Chris@16 916 }
Chris@16 917 catch(const std::exception&)
Chris@16 918 {
Chris@16 919 // conversion failed, just fall through, value is not an integer.
Chris@16 920 }
Chris@16 921 result = std::numeric_limits<number<mpfi_float_backend<Digits10>, et_on> >::quiet_NaN().backend();
Chris@16 922 return;
Chris@16 923 }
Chris@16 924 mpfi_log(result.data(), b.data());
Chris@16 925 mpfi_mul(result.data(), result.data(), e.data());
Chris@16 926 mpfi_exp(result.data(), result.data());
Chris@16 927 }
Chris@16 928
Chris@16 929 template <unsigned Digits10>
Chris@16 930 inline void eval_exp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
Chris@16 931 {
Chris@16 932 mpfi_exp(result.data(), arg.data());
Chris@16 933 }
Chris@16 934
Chris@16 935 template <unsigned Digits10>
Chris@16 936 inline void eval_log(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
Chris@16 937 {
Chris@16 938 mpfi_log(result.data(), arg.data());
Chris@16 939 }
Chris@16 940
Chris@16 941 template <unsigned Digits10>
Chris@16 942 inline void eval_log10(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
Chris@16 943 {
Chris@16 944 mpfi_log10(result.data(), arg.data());
Chris@16 945 }
Chris@16 946
Chris@16 947 template <unsigned Digits10>
Chris@16 948 inline void eval_sin(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
Chris@16 949 {
Chris@16 950 mpfi_sin(result.data(), arg.data());
Chris@16 951 }
Chris@16 952
Chris@16 953 template <unsigned Digits10>
Chris@16 954 inline void eval_cos(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
Chris@16 955 {
Chris@16 956 mpfi_cos(result.data(), arg.data());
Chris@16 957 }
Chris@16 958
Chris@16 959 template <unsigned Digits10>
Chris@16 960 inline void eval_tan(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
Chris@16 961 {
Chris@16 962 mpfi_tan(result.data(), arg.data());
Chris@16 963 }
Chris@16 964
Chris@16 965 template <unsigned Digits10>
Chris@16 966 inline void eval_asin(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
Chris@16 967 {
Chris@16 968 mpfi_asin(result.data(), arg.data());
Chris@16 969 }
Chris@16 970
Chris@16 971 template <unsigned Digits10>
Chris@16 972 inline void eval_acos(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
Chris@16 973 {
Chris@16 974 mpfi_acos(result.data(), arg.data());
Chris@16 975 }
Chris@16 976
Chris@16 977 template <unsigned Digits10>
Chris@16 978 inline void eval_atan(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
Chris@16 979 {
Chris@16 980 mpfi_atan(result.data(), arg.data());
Chris@16 981 }
Chris@16 982
Chris@16 983 template <unsigned Digits10>
Chris@16 984 inline void eval_atan2(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg1, const mpfi_float_backend<Digits10>& arg2)
Chris@16 985 {
Chris@16 986 mpfi_atan2(result.data(), arg1.data(), arg2.data());
Chris@16 987 }
Chris@16 988
Chris@16 989 template <unsigned Digits10>
Chris@16 990 inline void eval_sinh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
Chris@16 991 {
Chris@16 992 mpfi_sinh(result.data(), arg.data());
Chris@16 993 }
Chris@16 994
Chris@16 995 template <unsigned Digits10>
Chris@16 996 inline void eval_cosh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
Chris@16 997 {
Chris@16 998 mpfi_cosh(result.data(), arg.data());
Chris@16 999 }
Chris@16 1000
Chris@16 1001 template <unsigned Digits10>
Chris@16 1002 inline void eval_tanh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
Chris@16 1003 {
Chris@16 1004 mpfi_tanh(result.data(), arg.data());
Chris@16 1005 }
Chris@16 1006
Chris@16 1007 } // namespace backends
Chris@16 1008
Chris@16 1009 #ifdef BOOST_NO_SFINAE_EXPR
Chris@16 1010
Chris@16 1011 namespace detail{
Chris@16 1012
Chris@16 1013 template<unsigned D1, unsigned D2>
Chris@16 1014 struct is_explicitly_convertible<backends::mpfi_float_backend<D1>, backends::mpfi_float_backend<D2> > : public mpl::true_ {};
Chris@16 1015
Chris@16 1016 }
Chris@16 1017
Chris@16 1018 #endif
Chris@16 1019
Chris@16 1020 template<>
Chris@16 1021 struct number_category<detail::canonical<mpfi_t, backends::mpfi_float_backend<0> >::type> : public mpl::int_<number_kind_floating_point>{};
Chris@16 1022 template <unsigned Digits10>
Chris@16 1023 struct is_interval_number<backends::mpfi_float_backend<Digits10> > : public mpl::true_ {};
Chris@16 1024
Chris@16 1025 using boost::multiprecision::backends::mpfi_float_backend;
Chris@16 1026
Chris@16 1027 typedef number<mpfi_float_backend<50> > mpfi_float_50;
Chris@16 1028 typedef number<mpfi_float_backend<100> > mpfi_float_100;
Chris@16 1029 typedef number<mpfi_float_backend<500> > mpfi_float_500;
Chris@16 1030 typedef number<mpfi_float_backend<1000> > mpfi_float_1000;
Chris@16 1031 typedef number<mpfi_float_backend<0> > mpfi_float;
Chris@16 1032
Chris@16 1033 //
Chris@16 1034 // Special interval specific functions:
Chris@16 1035 //
Chris@16 1036 template <unsigned Digits10, expression_template_option ExpressionTemplates>
Chris@16 1037 inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> lower(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
Chris@16 1038 {
Chris@16 1039 number<mpfr_float_backend<Digits10> > result;
Chris@16 1040 mpfr_set(result.backend().data(), val.backend().left_data(), GMP_RNDN);
Chris@16 1041 return result;
Chris@16 1042 }
Chris@16 1043
Chris@16 1044 template <unsigned Digits10, expression_template_option ExpressionTemplates>
Chris@16 1045 inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> upper(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
Chris@16 1046 {
Chris@16 1047 number<mpfr_float_backend<Digits10> > result;
Chris@16 1048 mpfr_set(result.backend().data(), val.backend().right_data(), GMP_RNDN);
Chris@16 1049 return result;
Chris@16 1050 }
Chris@16 1051
Chris@16 1052 template <unsigned Digits10, expression_template_option ExpressionTemplates>
Chris@16 1053 inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> median(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
Chris@16 1054 {
Chris@16 1055 number<mpfr_float_backend<Digits10> > result;
Chris@16 1056 mpfi_mid(result.backend().data(), val.backend().data());
Chris@16 1057 return result;
Chris@16 1058 }
Chris@16 1059
Chris@16 1060 template <unsigned Digits10, expression_template_option ExpressionTemplates>
Chris@16 1061 inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> width(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
Chris@16 1062 {
Chris@16 1063 number<mpfr_float_backend<Digits10> > result;
Chris@16 1064 mpfi_diam_abs(result.backend().data(), val.backend().data());
Chris@16 1065 return result;
Chris@16 1066 }
Chris@16 1067
Chris@16 1068 template <unsigned Digits10, expression_template_option ExpressionTemplates>
Chris@16 1069 inline number<mpfi_float_backend<Digits10>, ExpressionTemplates> intersect(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
Chris@16 1070 {
Chris@16 1071 number<mpfi_float_backend<Digits10>, ExpressionTemplates> result;
Chris@16 1072 mpfi_intersect(result.backend().data(), a.backend().data(), b.backend().data());
Chris@16 1073 return result;
Chris@16 1074 }
Chris@16 1075
Chris@16 1076 template <unsigned Digits10, expression_template_option ExpressionTemplates>
Chris@16 1077 inline number<mpfi_float_backend<Digits10>, ExpressionTemplates> hull(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
Chris@16 1078 {
Chris@16 1079 number<mpfi_float_backend<Digits10>, ExpressionTemplates> result;
Chris@16 1080 mpfi_union(result.backend().data(), a.backend().data(), b.backend().data());
Chris@16 1081 return result;
Chris@16 1082 }
Chris@16 1083
Chris@16 1084 template <unsigned Digits10, expression_template_option ExpressionTemplates>
Chris@16 1085 inline bool overlap(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
Chris@16 1086 {
Chris@16 1087 return (lower(a) <= lower(b) && lower(b) <= upper(a)) ||
Chris@16 1088 (lower(b) <= lower(a) && lower(a) <= upper(b));
Chris@16 1089 }
Chris@16 1090
Chris@16 1091 template <unsigned Digits10, expression_template_option ExpressionTemplates1, expression_template_option ExpressionTemplates2>
Chris@16 1092 inline bool in(const number<mpfr_float_backend<Digits10>, ExpressionTemplates1>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates2>& b)
Chris@16 1093 {
Chris@16 1094 return mpfi_is_inside_fr(a.backend().data(), b.backend().data()) != 0;
Chris@16 1095 }
Chris@16 1096
Chris@16 1097 template <unsigned Digits10, expression_template_option ExpressionTemplates>
Chris@16 1098 inline bool zero_in(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a)
Chris@16 1099 {
Chris@16 1100 return mpfi_has_zero(a.backend().data()) != 0;
Chris@16 1101 }
Chris@16 1102
Chris@16 1103 template <unsigned Digits10, expression_template_option ExpressionTemplates>
Chris@16 1104 inline bool subset(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
Chris@16 1105 {
Chris@16 1106 return mpfi_is_inside(a.backend().data(), b.backend().data()) != 0;
Chris@16 1107 }
Chris@16 1108
Chris@16 1109 template <unsigned Digits10, expression_template_option ExpressionTemplates>
Chris@16 1110 inline bool proper_subset(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
Chris@16 1111 {
Chris@16 1112 return mpfi_is_strictly_inside(a.backend().data(), b.backend().data()) != 0;
Chris@16 1113 }
Chris@16 1114
Chris@16 1115 template <unsigned Digits10, expression_template_option ExpressionTemplates>
Chris@16 1116 inline bool empty(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a)
Chris@16 1117 {
Chris@16 1118 return mpfi_is_empty(a.backend().data()) != 0;
Chris@16 1119 }
Chris@16 1120
Chris@16 1121 template <unsigned Digits10, expression_template_option ExpressionTemplates>
Chris@16 1122 inline bool singleton(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a)
Chris@16 1123 {
Chris@16 1124 return mpfr_cmp(a.backend().left_data(), a.backend().right_data()) == 0;
Chris@16 1125 }
Chris@16 1126
Chris@16 1127 template <unsigned Digits10, expression_template_option ExpressionTemplates>
Chris@16 1128 struct component_type<number<mpfi_float_backend<Digits10>, ExpressionTemplates> >
Chris@16 1129 {
Chris@16 1130 typedef number<mpfr_float_backend<Digits10>, ExpressionTemplates> type;
Chris@16 1131 };
Chris@16 1132
Chris@16 1133 } // namespace multiprecision
Chris@16 1134
Chris@16 1135 namespace math{
Chris@16 1136
Chris@16 1137 namespace tools{
Chris@16 1138
Chris@16 1139 template <>
Chris@16 1140 inline int digits<boost::multiprecision::mpfi_float>()
Chris@16 1141 {
Chris@16 1142 return boost::multiprecision::backends::detail::get_default_precision();
Chris@16 1143 }
Chris@16 1144 template <>
Chris@16 1145 inline int digits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> >()
Chris@16 1146 {
Chris@16 1147 return boost::multiprecision::backends::detail::get_default_precision();
Chris@16 1148 }
Chris@16 1149
Chris@16 1150 } // namespace tools
Chris@16 1151
Chris@16 1152 namespace constants{ namespace detail{
Chris@16 1153
Chris@16 1154 template <class T> struct constant_pi;
Chris@16 1155 template <class T> struct constant_ln_two;
Chris@16 1156 template <class T> struct constant_euler;
Chris@16 1157 template <class T> struct constant_catalan;
Chris@16 1158
Chris@16 1159 //
Chris@16 1160 // Initializer: ensure all our constants are initialized prior to the first call of main:
Chris@16 1161 //
Chris@16 1162 template <class T>
Chris@16 1163 struct mpfi_initializer
Chris@16 1164 {
Chris@16 1165 struct init
Chris@16 1166 {
Chris@16 1167 init()
Chris@16 1168 {
Chris@16 1169 boost::math::constants::pi<T>();
Chris@16 1170 boost::math::constants::ln_two<T>();
Chris@16 1171 boost::math::constants::euler<T>();
Chris@16 1172 boost::math::constants::catalan<T>();
Chris@16 1173 }
Chris@16 1174 void force_instantiate()const{}
Chris@16 1175 };
Chris@16 1176 static const init initializer;
Chris@16 1177 static void force_instantiate()
Chris@16 1178 {
Chris@16 1179 initializer.force_instantiate();
Chris@16 1180 }
Chris@16 1181 };
Chris@16 1182
Chris@16 1183 template <class T>
Chris@16 1184 const typename mpfi_initializer<T>::init mpfi_initializer<T>::initializer;
Chris@16 1185
Chris@16 1186 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1187 struct constant_pi<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
Chris@16 1188 {
Chris@16 1189 typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type;
Chris@16 1190 template<int N>
Chris@16 1191 static inline result_type const& get(const mpl::int_<N>&)
Chris@16 1192 {
Chris@16 1193 mpfi_initializer<result_type>::force_instantiate();
Chris@16 1194 static result_type result;
Chris@16 1195 static bool has_init = false;
Chris@16 1196 if(!has_init)
Chris@16 1197 {
Chris@16 1198 has_init = true;
Chris@16 1199 mpfi_const_pi(result.backend().data());
Chris@16 1200 }
Chris@16 1201 return result;
Chris@16 1202 }
Chris@16 1203 };
Chris@16 1204 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1205 struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
Chris@16 1206 {
Chris@16 1207 typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type;
Chris@16 1208 template<int N>
Chris@16 1209 static inline result_type const& get(const mpl::int_<N>&)
Chris@16 1210 {
Chris@16 1211 mpfi_initializer<result_type>::force_instantiate();
Chris@16 1212 static result_type result;
Chris@16 1213 static bool has_init = false;
Chris@16 1214 if(!has_init)
Chris@16 1215 {
Chris@16 1216 has_init = true;
Chris@16 1217 mpfi_const_log2(result.backend().data());
Chris@16 1218 }
Chris@16 1219 return result;
Chris@16 1220 }
Chris@16 1221 };
Chris@16 1222 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1223 struct constant_euler<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
Chris@16 1224 {
Chris@16 1225 typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type;
Chris@16 1226 template<int N>
Chris@16 1227 static inline result_type const& get(const mpl::int_<N>&)
Chris@16 1228 {
Chris@16 1229 mpfi_initializer<result_type>::force_instantiate();
Chris@16 1230 static result_type result;
Chris@16 1231 static bool has_init = false;
Chris@16 1232 if(!has_init)
Chris@16 1233 {
Chris@16 1234 has_init = true;
Chris@16 1235 mpfi_const_euler(result.backend().data());
Chris@16 1236 }
Chris@16 1237 return result;
Chris@16 1238 }
Chris@16 1239 };
Chris@16 1240 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1241 struct constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
Chris@16 1242 {
Chris@16 1243 typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type;
Chris@16 1244 template<int N>
Chris@16 1245 static inline result_type const& get(const mpl::int_<N>&)
Chris@16 1246 {
Chris@16 1247 mpfi_initializer<result_type>::force_instantiate();
Chris@16 1248 static result_type result;
Chris@16 1249 static bool has_init = false;
Chris@16 1250 if(!has_init)
Chris@16 1251 {
Chris@16 1252 has_init = true;
Chris@16 1253 mpfi_const_catalan(result.backend().data());
Chris@16 1254 }
Chris@16 1255 return result;
Chris@16 1256 }
Chris@16 1257 };
Chris@16 1258
Chris@16 1259 }} // namespaces
Chris@16 1260
Chris@16 1261 }} // namespaces
Chris@16 1262
Chris@16 1263 namespace std{
Chris@16 1264
Chris@16 1265 //
Chris@16 1266 // numeric_limits [partial] specializations for the types declared in this header:
Chris@16 1267 //
Chris@16 1268 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1269 class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
Chris@16 1270 {
Chris@16 1271 typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> number_type;
Chris@16 1272 public:
Chris@16 1273 BOOST_STATIC_CONSTEXPR bool is_specialized = true;
Chris@16 1274 static number_type (min)()
Chris@16 1275 {
Chris@16 1276 initializer.do_nothing();
Chris@16 1277 static std::pair<bool, number_type> value;
Chris@16 1278 if(!value.first)
Chris@16 1279 {
Chris@16 1280 value.first = true;
Chris@16 1281 value.second = 0.5;
Chris@16 1282 mpfi_div_2exp(value.second.backend().data(), value.second.backend().data(), -mpfr_get_emin());
Chris@16 1283 }
Chris@16 1284 return value.second;
Chris@16 1285 }
Chris@16 1286 static number_type (max)()
Chris@16 1287 {
Chris@16 1288 initializer.do_nothing();
Chris@16 1289 static std::pair<bool, number_type> value;
Chris@16 1290 if(!value.first)
Chris@16 1291 {
Chris@16 1292 value.first = true;
Chris@16 1293 value.second = 0.5;
Chris@16 1294 mpfi_mul_2exp(value.second.backend().data(), value.second.backend().data(), mpfr_get_emax());
Chris@16 1295 }
Chris@16 1296 return value.second;
Chris@16 1297 }
Chris@16 1298 BOOST_STATIC_CONSTEXPR number_type lowest()
Chris@16 1299 {
Chris@16 1300 return -(max)();
Chris@16 1301 }
Chris@16 1302 BOOST_STATIC_CONSTEXPR int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301 ? 2 : 1));
Chris@16 1303 BOOST_STATIC_CONSTEXPR int digits10 = Digits10;
Chris@16 1304 // Is this really correct???
Chris@16 1305 BOOST_STATIC_CONSTEXPR int max_digits10 = Digits10 + 2;
Chris@16 1306 BOOST_STATIC_CONSTEXPR bool is_signed = true;
Chris@16 1307 BOOST_STATIC_CONSTEXPR bool is_integer = false;
Chris@16 1308 BOOST_STATIC_CONSTEXPR bool is_exact = false;
Chris@16 1309 BOOST_STATIC_CONSTEXPR int radix = 2;
Chris@16 1310 static number_type epsilon()
Chris@16 1311 {
Chris@16 1312 initializer.do_nothing();
Chris@16 1313 static std::pair<bool, number_type> value;
Chris@16 1314 if(!value.first)
Chris@16 1315 {
Chris@16 1316 value.first = true;
Chris@16 1317 value.second = 1;
Chris@16 1318 mpfi_div_2exp(value.second.backend().data(), value.second.backend().data(), std::numeric_limits<number_type>::digits - 1);
Chris@16 1319 }
Chris@16 1320 return value.second;
Chris@16 1321 }
Chris@16 1322 // What value should this be????
Chris@16 1323 static number_type round_error()
Chris@16 1324 {
Chris@16 1325 // returns epsilon/2
Chris@16 1326 initializer.do_nothing();
Chris@16 1327 static std::pair<bool, number_type> value;
Chris@16 1328 if(!value.first)
Chris@16 1329 {
Chris@16 1330 value.first = true;
Chris@16 1331 value.second = 1;
Chris@16 1332 mpfi_div_2exp(value.second.backend().data(), value.second.backend().data(), 1);
Chris@16 1333 }
Chris@16 1334 return value.second;
Chris@16 1335 }
Chris@16 1336 BOOST_STATIC_CONSTEXPR long min_exponent = MPFR_EMIN_DEFAULT;
Chris@16 1337 BOOST_STATIC_CONSTEXPR long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
Chris@16 1338 BOOST_STATIC_CONSTEXPR long max_exponent = MPFR_EMAX_DEFAULT;
Chris@16 1339 BOOST_STATIC_CONSTEXPR long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
Chris@16 1340 BOOST_STATIC_CONSTEXPR bool has_infinity = true;
Chris@16 1341 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true;
Chris@16 1342 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
Chris@16 1343 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
Chris@16 1344 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
Chris@16 1345 static number_type infinity()
Chris@16 1346 {
Chris@16 1347 initializer.do_nothing();
Chris@16 1348 static std::pair<bool, number_type> value;
Chris@16 1349 if(!value.first)
Chris@16 1350 {
Chris@16 1351 boost::multiprecision::mpfr_float_backend<Digits10> t;
Chris@16 1352 mpfr_set_inf(t.data(), 1);
Chris@16 1353 value.first = true;
Chris@16 1354 mpfi_set_fr(value.second.backend().data(), t.data());
Chris@16 1355 }
Chris@16 1356 return value.second;
Chris@16 1357 }
Chris@16 1358 static number_type quiet_NaN()
Chris@16 1359 {
Chris@16 1360 initializer.do_nothing();
Chris@16 1361 static std::pair<bool, number_type> value;
Chris@16 1362 if(!value.first)
Chris@16 1363 {
Chris@16 1364 boost::multiprecision::mpfr_float_backend<Digits10> t;
Chris@16 1365 mpfr_set_nan(t.data());
Chris@16 1366 value.first = true;
Chris@16 1367 mpfi_set_fr(value.second.backend().data(), t.data());
Chris@16 1368 }
Chris@16 1369 return value.second;
Chris@16 1370 }
Chris@16 1371 BOOST_STATIC_CONSTEXPR number_type signaling_NaN()
Chris@16 1372 {
Chris@16 1373 return number_type(0);
Chris@16 1374 }
Chris@16 1375 BOOST_STATIC_CONSTEXPR number_type denorm_min() { return number_type(0); }
Chris@16 1376 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
Chris@16 1377 BOOST_STATIC_CONSTEXPR bool is_bounded = true;
Chris@16 1378 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
Chris@16 1379 BOOST_STATIC_CONSTEXPR bool traps = true;
Chris@16 1380 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
Chris@16 1381 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest;
Chris@16 1382
Chris@16 1383 private:
Chris@16 1384 struct data_initializer
Chris@16 1385 {
Chris@16 1386 data_initializer()
Chris@16 1387 {
Chris@16 1388 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::epsilon();
Chris@16 1389 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::round_error();
Chris@16 1390 (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::min)();
Chris@16 1391 (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::max)();
Chris@16 1392 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::infinity();
Chris@16 1393 std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::quiet_NaN();
Chris@16 1394 }
Chris@16 1395 void do_nothing()const{}
Chris@16 1396 };
Chris@16 1397 static const data_initializer initializer;
Chris@16 1398 };
Chris@16 1399
Chris@16 1400 template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1401 const typename numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::data_initializer numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::initializer;
Chris@16 1402
Chris@16 1403 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
Chris@16 1404
Chris@16 1405 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1406 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::digits;
Chris@16 1407 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1408 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::digits10;
Chris@16 1409 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1410 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_digits10;
Chris@16 1411 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1412 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_signed;
Chris@16 1413 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1414 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_integer;
Chris@16 1415 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1416 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_exact;
Chris@16 1417 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1418 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::radix;
Chris@16 1419 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1420 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::min_exponent;
Chris@16 1421 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1422 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::min_exponent10;
Chris@16 1423 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1424 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_exponent;
Chris@16 1425 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1426 BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_exponent10;
Chris@16 1427 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1428 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_infinity;
Chris@16 1429 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1430 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_quiet_NaN;
Chris@16 1431 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1432 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_signaling_NaN;
Chris@16 1433 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1434 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_denorm;
Chris@16 1435 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1436 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_denorm_loss;
Chris@16 1437 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1438 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_iec559;
Chris@16 1439 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1440 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_bounded;
Chris@16 1441 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1442 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_modulo;
Chris@16 1443 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1444 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::traps;
Chris@16 1445 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1446 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::tinyness_before;
Chris@16 1447 template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1448 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::round_style;
Chris@16 1449
Chris@16 1450 #endif
Chris@16 1451
Chris@16 1452
Chris@16 1453 template<boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1454 class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >
Chris@16 1455 {
Chris@16 1456 typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> number_type;
Chris@16 1457 public:
Chris@16 1458 BOOST_STATIC_CONSTEXPR bool is_specialized = false;
Chris@16 1459 static number_type (min)() { return number_type(0); }
Chris@16 1460 static number_type (max)() { return number_type(0); }
Chris@16 1461 static number_type lowest() { return number_type(0); }
Chris@16 1462 BOOST_STATIC_CONSTEXPR int digits = 0;
Chris@16 1463 BOOST_STATIC_CONSTEXPR int digits10 = 0;
Chris@16 1464 BOOST_STATIC_CONSTEXPR int max_digits10 = 0;
Chris@16 1465 BOOST_STATIC_CONSTEXPR bool is_signed = false;
Chris@16 1466 BOOST_STATIC_CONSTEXPR bool is_integer = false;
Chris@16 1467 BOOST_STATIC_CONSTEXPR bool is_exact = false;
Chris@16 1468 BOOST_STATIC_CONSTEXPR int radix = 0;
Chris@16 1469 static number_type epsilon() { return number_type(0); }
Chris@16 1470 static number_type round_error() { return number_type(0); }
Chris@16 1471 BOOST_STATIC_CONSTEXPR int min_exponent = 0;
Chris@16 1472 BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
Chris@16 1473 BOOST_STATIC_CONSTEXPR int max_exponent = 0;
Chris@16 1474 BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
Chris@16 1475 BOOST_STATIC_CONSTEXPR bool has_infinity = false;
Chris@16 1476 BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
Chris@16 1477 BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
Chris@16 1478 BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
Chris@16 1479 BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
Chris@16 1480 static number_type infinity() { return number_type(0); }
Chris@16 1481 static number_type quiet_NaN() { return number_type(0); }
Chris@16 1482 static number_type signaling_NaN() { return number_type(0); }
Chris@16 1483 static number_type denorm_min() { return number_type(0); }
Chris@16 1484 BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
Chris@16 1485 BOOST_STATIC_CONSTEXPR bool is_bounded = false;
Chris@16 1486 BOOST_STATIC_CONSTEXPR bool is_modulo = false;
Chris@16 1487 BOOST_STATIC_CONSTEXPR bool traps = false;
Chris@16 1488 BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
Chris@16 1489 BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
Chris@16 1490 };
Chris@16 1491
Chris@16 1492 #ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
Chris@16 1493
Chris@16 1494 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1495 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::digits;
Chris@16 1496 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1497 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::digits10;
Chris@16 1498 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1499 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_digits10;
Chris@16 1500 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1501 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_signed;
Chris@16 1502 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1503 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_integer;
Chris@16 1504 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1505 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_exact;
Chris@16 1506 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1507 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::radix;
Chris@16 1508 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1509 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::min_exponent;
Chris@16 1510 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1511 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::min_exponent10;
Chris@16 1512 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1513 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_exponent;
Chris@16 1514 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1515 BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_exponent10;
Chris@16 1516 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1517 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_infinity;
Chris@16 1518 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1519 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_quiet_NaN;
Chris@16 1520 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1521 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_signaling_NaN;
Chris@16 1522 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1523 BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_denorm;
Chris@16 1524 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1525 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_denorm_loss;
Chris@16 1526 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1527 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_iec559;
Chris@16 1528 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1529 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_bounded;
Chris@16 1530 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1531 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_modulo;
Chris@16 1532 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1533 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::traps;
Chris@16 1534 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1535 BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::tinyness_before;
Chris@16 1536 template <boost::multiprecision::expression_template_option ExpressionTemplates>
Chris@16 1537 BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::round_style;
Chris@16 1538
Chris@16 1539 #endif
Chris@16 1540 } // namespace std
Chris@16 1541 #endif