Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r82337 - in trunk: boost/multiprecision boost/multiprecision/cpp_int boost/multiprecision/detail libs/multiprecision/config libs/multiprecision/test
From: john_at_[hidden]
Date: 2013-01-03 13:58:46


Author: johnmaddock
Date: 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
New Revision: 82337
URL: http://svn.boost.org/trac/boost/changeset/82337

Log:
Add initial support for mpfi interval arithmetic
Added:
   trunk/boost/multiprecision/mpfi.hpp (contents, props changed)
   trunk/libs/multiprecision/config/has_mpfi.cpp (contents, props changed)
   trunk/libs/multiprecision/test/test_arithmetic_mpfi_50.cpp (contents, props changed)
   trunk/libs/multiprecision/test/test_mpfi.cpp (contents, props changed)
Text files modified:
   trunk/boost/multiprecision/cpp_int/misc.hpp | 2
   trunk/boost/multiprecision/detail/number_base.hpp | 4
   trunk/libs/multiprecision/config/Jamfile.v2 | 9
   trunk/libs/multiprecision/test/Jamfile.v2 | 389 +++++----------------------------------
   trunk/libs/multiprecision/test/test.hpp | 12 +
   trunk/libs/multiprecision/test/test_acos.cpp | 10
   trunk/libs/multiprecision/test/test_asin.cpp | 10
   trunk/libs/multiprecision/test/test_atan.cpp | 20 +
   trunk/libs/multiprecision/test/test_cos.cpp | 10
   trunk/libs/multiprecision/test/test_cosh.cpp | 10
   trunk/libs/multiprecision/test/test_exp.cpp | 10
   trunk/libs/multiprecision/test/test_float_io.cpp | 13 +
   trunk/libs/multiprecision/test/test_fpclassify.cpp | 10
   trunk/libs/multiprecision/test/test_log.cpp | 11 +
   trunk/libs/multiprecision/test/test_numeric_limits.cpp | 10
   trunk/libs/multiprecision/test/test_pow.cpp | 10
   trunk/libs/multiprecision/test/test_round.cpp | 29 ++
   trunk/libs/multiprecision/test/test_sin.cpp | 12 +
   trunk/libs/multiprecision/test/test_sinh.cpp | 12 +
   trunk/libs/multiprecision/test/test_sqrt.cpp | 12 +
   trunk/libs/multiprecision/test/test_tan.cpp | 11
   trunk/libs/multiprecision/test/test_tanh.cpp | 12 +
   22 files changed, 262 insertions(+), 366 deletions(-)

Modified: trunk/boost/multiprecision/cpp_int/misc.hpp
==============================================================================
--- trunk/boost/multiprecision/cpp_int/misc.hpp (original)
+++ trunk/boost/multiprecision/cpp_int/misc.hpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -579,7 +579,7 @@
    //
    // Find the index of the least significant bit within that limb:
    //
- return find_lsb(*a.limbs(), mpl::int_<CHAR_BIT * sizeof(cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::local_limb_type)>());
+ return find_lsb(*a.limbs(), mpl::int_<CHAR_BIT * sizeof(typename cpp_int_backend<MinBits1, MaxBits1, SignType1, Checked1, Allocator1>::local_limb_type)>());
 }
 
 #ifdef BOOST_MSVC

Modified: trunk/boost/multiprecision/detail/number_base.hpp
==============================================================================
--- trunk/boost/multiprecision/detail/number_base.hpp (original)
+++ trunk/boost/multiprecision/detail/number_base.hpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -701,6 +701,10 @@
 struct is_unsigned_number<number<Backend, ExpressionTemplates> > : public is_unsigned_number<Backend> {};
 template <class T>
 struct is_signed_number : public mpl::bool_<!is_unsigned_number<T>::value> {};
+template <class T>
+struct is_interval_number : public mpl::false_ {};
+template <class Backend, expression_template_option ExpressionTemplates>
+struct is_interval_number<number<Backend, ExpressionTemplates> > : public is_interval_number<Backend>{};
 
 }} // namespaces
 

Added: trunk/boost/multiprecision/mpfi.hpp
==============================================================================
--- (empty file)
+++ trunk/boost/multiprecision/mpfi.hpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -0,0 +1,1402 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2011 John Maddock. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifndef BOOST_MATH_BN_MPFI_HPP
+#define BOOST_MATH_BN_MPFI_HPP
+
+#include <boost/multiprecision/number.hpp>
+#include <boost/math/special_functions/fpclassify.hpp>
+#include <boost/cstdint.hpp>
+#include <boost/multiprecision/detail/big_lanczos.hpp>
+#include <boost/multiprecision/detail/digits.hpp>
+#include <boost/multiprecision/mpfr.hpp>
+#include <mpfi.h>
+#include <cmath>
+#include <algorithm>
+
+namespace boost{
+namespace multiprecision{
+namespace backends{
+
+template <unsigned digits10>
+struct mpfi_float_backend;
+
+} // namespace backends
+
+template <unsigned digits10>
+struct number_category<backends::mpfi_float_backend<digits10> > : public mpl::int_<number_kind_floating_point>{};
+
+struct interval_error : public std::runtime_error
+{
+ interval_error(const std::string& s) : std::runtime_error(s) {}
+};
+
+namespace backends{
+
+namespace detail{
+
+inline int mpfi_sgn(mpfi_srcptr p)
+{
+ if(mpfi_is_zero(p))
+ return 0;
+ if(mpfi_is_strictly_pos(p))
+ return 1;
+ if(mpfi_is_strictly_neg(p))
+ return -1;
+ BOOST_THROW_EXCEPTION(interval_error("Sign of interval is ambiguous."));
+}
+
+template <unsigned digits10>
+struct mpfi_float_imp;
+
+template <unsigned digits10>
+struct mpfi_float_imp
+{
+ typedef mpl::list<long, long long> signed_types;
+ typedef mpl::list<unsigned long, unsigned long long> unsigned_types;
+ typedef mpl::list<double, long double> float_types;
+ typedef long exponent_type;
+
+ mpfi_float_imp()
+ {
+ mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+ }
+ mpfi_float_imp(unsigned prec)
+ {
+ mpfi_init2(m_data, prec);
+ }
+
+ mpfi_float_imp(const mpfi_float_imp& o)
+ {
+ mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+ if(o.m_data[0].left._mpfr_d)
+ mpfi_set(m_data, o.m_data);
+ }
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ mpfi_float_imp(mpfi_float_imp&& o) BOOST_NOEXCEPT
+ {
+ m_data[0] = o.m_data[0];
+ o.m_data[0].left._mpfr_d = 0;
+ }
+#endif
+ mpfi_float_imp& operator = (const mpfi_float_imp& o)
+ {
+ if(m_data[0].left._mpfr_d == 0)
+ mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+ if(o.m_data[0].left._mpfr_d)
+ mpfi_set(m_data, o.m_data);
+ return *this;
+ }
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ mpfi_float_imp& operator = (mpfi_float_imp&& o) BOOST_NOEXCEPT
+ {
+ mpfi_swap(m_data, o.m_data);
+ return *this;
+ }
+#endif
+#ifdef _MPFR_H_HAVE_INTMAX_T
+ mpfi_float_imp& operator = (unsigned long long i)
+ {
+ if(m_data[0].left._mpfr_d == 0)
+ mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+ mpfr_set_uj(left_data(), i, GMP_RNDD);
+ mpfr_set_uj(right_data(), i, GMP_RNDU);
+ return *this;
+ }
+ mpfi_float_imp& operator = (long long i)
+ {
+ if(m_data[0].left._mpfr_d == 0)
+ mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+ mpfr_set_sj(left_data(), i, GMP_RNDD);
+ mpfr_set_sj(right_data(), i, GMP_RNDU);
+ return *this;
+ }
+#else
+ mpfi_float_imp& operator = (unsigned long long i)
+ {
+ if(m_data[0].left._mpfr_d == 0)
+ mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+ unsigned long long mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
+ unsigned shift = 0;
+ mpfi_t t;
+ mpfi_init2(t, (std::max)(static_cast<unsigned>(std::numeric_limits<unsigned long long>::digits), static_cast<unsigned>(multiprecision::detail::digits10_2_2(digits10))));
+ mpfi_set_ui(m_data, 0);
+ while(i)
+ {
+ mpfi_set_ui(t, static_cast<unsigned>(i & mask));
+ if(shift)
+ mpfi_mul_2exp(t, t, shift);
+ mpfi_add(m_data, m_data, t);
+ shift += std::numeric_limits<unsigned>::digits;
+ i >>= std::numeric_limits<unsigned>::digits;
+ }
+ mpfi_clear(t);
+ return *this;
+ }
+ mpfi_float_imp& operator = (long long i)
+ {
+ BOOST_MP_USING_ABS
+ if(m_data[0].left._mpfr_d == 0)
+ mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+ bool neg = i < 0;
+ *this = static_cast<unsigned long long>(abs(i));
+ if(neg)
+ mpfi_neg(m_data, m_data);
+ return *this;
+ }
+#endif
+ mpfi_float_imp& operator = (unsigned long i)
+ {
+ if(m_data[0].left._mpfr_d == 0)
+ mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+ mpfi_set_ui(m_data, i);
+ return *this;
+ }
+ mpfi_float_imp& operator = (long i)
+ {
+ if(m_data[0].left._mpfr_d == 0)
+ mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+ mpfi_set_si(m_data, i);
+ return *this;
+ }
+ mpfi_float_imp& operator = (double d)
+ {
+ if(m_data[0].left._mpfr_d == 0)
+ mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+ mpfi_set_d(m_data, d);
+ return *this;
+ }
+ mpfi_float_imp& operator = (long double a)
+ {
+ if(m_data[0].left._mpfr_d == 0)
+ mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+ mpfr_set_ld(left_data(), a, GMP_RNDD);
+ mpfr_set_ld(right_data(), a, GMP_RNDU);
+ return *this;
+ }
+ mpfi_float_imp& operator = (const char* s)
+ {
+ if(m_data[0].left._mpfr_d == 0)
+ mpfi_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+
+ if(s && (*s == '{'))
+ {
+ mpfr_float_backend<digits10> a, b;
+ std::string part;
+ const char* p = ++s;
+ while(*p && (*p != ',') && (*p != '}'))
+ ++p;
+ part.assign(s + 1, p);
+ a = part.c_str();
+ s = p;
+ if(*p && (*p != '}'))
+ {
+ ++p;
+ while(*p && (*p != ',') && (*p != '}'))
+ ++p;
+ part.assign(s + 1, p);
+ }
+ else
+ part.erase();
+ b = part.c_str();
+
+ mpfi_interv_fr(m_data, a.data(), b.data());
+ }
+ else if(mpfi_set_str(m_data, s, 10) != 0)
+ {
+ BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
+ }
+ return *this;
+ }
+ void swap(mpfi_float_imp& o) BOOST_NOEXCEPT
+ {
+ mpfi_swap(m_data, o.m_data);
+ }
+ std::string str(std::streamsize digits, std::ios_base::fmtflags f)const
+ {
+ BOOST_ASSERT(m_data[0].left._mpfr_d);
+
+ mpfr_float_backend<digits10> a, b;
+
+ mpfi_get_left(a.data(), m_data);
+ mpfi_get_right(b.data(), m_data);
+
+ if(a.compare(b) == 0)
+ return a.str(digits, f);
+
+ return "{" + a.str(digits, f) + "," + b.str(digits, f) + "}";
+ }
+ ~mpfi_float_imp() BOOST_NOEXCEPT
+ {
+ if(m_data[0].left._mpfr_d)
+ mpfi_clear(m_data);
+ }
+ void negate() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT(m_data[0].left._mpfr_d);
+ mpfi_neg(m_data, m_data);
+ }
+ int compare(const mpfi_float_imp& o)const BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT(m_data[0].left._mpfr_d && o.m_data[0].left._mpfr_d);
+ if(mpfr_cmp(right_data(), o.left_data()) < 0)
+ return -1;
+ if(mpfr_cmp(left_data(), o.right_data()) > 0)
+ return 1;
+ if((mpfr_cmp(left_data(), o.left_data()) == 0) && (mpfr_cmp(right_data(), o.right_data()) == 0))
+ return 0;
+ BOOST_THROW_EXCEPTION(interval_error("Ambiguous comparison between two values."));
+ return 0;
+ }
+ template <class V>
+ int compare(V v)const BOOST_NOEXCEPT
+ {
+ mpfi_float_imp d;
+ d = v;
+ return compare(d);
+ }
+ mpfi_t& data() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT(m_data[0].left._mpfr_d);
+ return m_data;
+ }
+ const mpfi_t& data()const BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT(m_data[0].left._mpfr_d);
+ return m_data;
+ }
+ mpfr_ptr left_data() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT(m_data[0].left._mpfr_d);
+ return &(m_data[0].left);
+ }
+ mpfr_srcptr left_data()const BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT(m_data[0].left._mpfr_d);
+ return &(m_data[0].left);
+ }
+ mpfr_ptr right_data() BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT(m_data[0].left._mpfr_d);
+ return &(m_data[0].right);
+ }
+ mpfr_srcptr right_data()const BOOST_NOEXCEPT
+ {
+ BOOST_ASSERT(m_data[0].left._mpfr_d);
+ return &(m_data[0].right);
+ }
+protected:
+ mpfi_t m_data;
+ static unsigned& get_default_precision() BOOST_NOEXCEPT
+ {
+ static unsigned val = 50;
+ return val;
+ }
+};
+
+} // namespace detail
+
+template <unsigned digits10>
+struct mpfi_float_backend : public detail::mpfi_float_imp<digits10>
+{
+ mpfi_float_backend() : detail::mpfi_float_imp<digits10>() {}
+ mpfi_float_backend(const mpfi_float_backend& o) : detail::mpfi_float_imp<digits10>(o) {}
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ mpfi_float_backend(mpfi_float_backend&& o) : detail::mpfi_float_imp<digits10>(static_cast<detail::mpfi_float_imp<digits10>&&>(o)) {}
+#endif
+ template <unsigned D>
+ mpfi_float_backend(const mpfi_float_backend<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
+ : detail::mpfi_float_imp<digits10>()
+ {
+ mpfi_set(this->m_data, val.data());
+ }
+ template <unsigned D>
+ explicit mpfi_float_backend(const mpfi_float_backend<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
+ : detail::mpfi_float_imp<digits10>()
+ {
+ mpfi_set(this->m_data, val.data());
+ }
+ mpfi_float_backend(const mpfi_t val)
+ : detail::mpfi_float_imp<digits10>()
+ {
+ mpfi_set(this->m_data, val);
+ }
+ mpfi_float_backend& operator=(const mpfi_float_backend& o)
+ {
+ *static_cast<detail::mpfi_float_imp<digits10>*>(this) = static_cast<detail::mpfi_float_imp<digits10> const&>(o);
+ return *this;
+ }
+ template <unsigned D>
+ mpfi_float_backend(const mpfr_float_backend<D>& val, typename enable_if_c<D <= digits10>::type* = 0)
+ : detail::mpfi_float_imp<digits10>()
+ {
+ mpfi_set_fr(this->m_data, val.data());
+ }
+ template <unsigned D>
+ mpfi_float_backend& operator=(const mpfr_float_backend<D>& val)
+ {
+ mpfi_set_fr(this->m_data, val.data());
+ return *this;
+ }
+ template <unsigned D>
+ explicit mpfi_float_backend(const mpfr_float_backend<D>& val, typename disable_if_c<D <= digits10>::type* = 0)
+ : detail::mpfi_float_imp<digits10>()
+ {
+ mpfi_set_fr(this->m_data, val.data());
+ }
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ mpfi_float_backend& operator=(mpfi_float_backend&& o) BOOST_NOEXCEPT
+ {
+ *static_cast<detail::mpfi_float_imp<digits10>*>(this) = static_cast<detail::mpfi_float_imp<digits10>&&>(o);
+ return *this;
+ }
+#endif
+ template <class V>
+ mpfi_float_backend& operator=(const V& v)
+ {
+ *static_cast<detail::mpfi_float_imp<digits10>*>(this) = v;
+ return *this;
+ }
+ mpfi_float_backend& operator=(const mpfi_t val)
+ {
+ mpfi_set(this->m_data, val);
+ return *this;
+ }
+ // We don't change our precision here, this is a fixed precision type:
+ template <unsigned D>
+ mpfi_float_backend& operator=(const mpfi_float_backend<D>& val)
+ {
+ mpfi_set(this->m_data, val.data());
+ return *this;
+ }
+};
+
+template <>
+struct mpfi_float_backend<0> : public detail::mpfi_float_imp<0>
+{
+ mpfi_float_backend() : detail::mpfi_float_imp<0>() {}
+ mpfi_float_backend(const mpfi_t val)
+ : detail::mpfi_float_imp<0>(mpfi_get_prec(val))
+ {
+ mpfi_set(this->m_data, val);
+ }
+ mpfi_float_backend(const mpfi_float_backend& o) : detail::mpfi_float_imp<0>(o) {}
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ mpfi_float_backend(mpfi_float_backend&& o) BOOST_NOEXCEPT : detail::mpfi_float_imp<0>(static_cast<detail::mpfi_float_imp<0>&&>(o)) {}
+#endif
+ mpfi_float_backend(const mpfi_float_backend& o, unsigned digits10)
+ : detail::mpfi_float_imp<0>(digits10)
+ {
+ *this = o;
+ }
+ template <unsigned D>
+ mpfi_float_backend(const mpfi_float_backend<D>& val)
+ : detail::mpfi_float_imp<0>(mpfi_get_prec(val.data()))
+ {
+ mpfi_set(this->m_data, val.data());
+ }
+ mpfi_float_backend& operator=(const mpfi_float_backend& o)
+ {
+ mpfi_set_prec(this->m_data, mpfi_get_prec(o.data()));
+ mpfi_set(this->m_data, o.data());
+ return *this;
+ }
+#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
+ mpfi_float_backend& operator=(mpfi_float_backend&& o) BOOST_NOEXCEPT
+ {
+ *static_cast<detail::mpfi_float_imp<0>*>(this) = static_cast<detail::mpfi_float_imp<0> &&>(o);
+ return *this;
+ }
+#endif
+ template <class V>
+ mpfi_float_backend& operator=(const V& v)
+ {
+ *static_cast<detail::mpfi_float_imp<0>*>(this) = v;
+ return *this;
+ }
+ mpfi_float_backend& operator=(const mpfi_t val)
+ {
+ mpfi_set_prec(this->m_data, mpfi_get_prec(val));
+ mpfi_set(this->m_data, val);
+ return *this;
+ }
+ template <unsigned D>
+ mpfi_float_backend& operator=(const mpfi_float_backend<D>& val)
+ {
+ mpfi_set_prec(this->m_data, mpfi_get_prec(val.data()));
+ mpfi_set(this->m_data, val.data());
+ return *this;
+ }
+ static unsigned default_precision() BOOST_NOEXCEPT
+ {
+ return get_default_precision();
+ }
+ static void default_precision(unsigned v) BOOST_NOEXCEPT
+ {
+ get_default_precision() = v;
+ }
+ unsigned precision()const BOOST_NOEXCEPT
+ {
+ return multiprecision::detail::digits2_2_10(mpfi_get_prec(this->m_data));
+ }
+ void precision(unsigned digits10) BOOST_NOEXCEPT
+ {
+ mpfi_set_prec(this->m_data, multiprecision::detail::digits2_2_10((digits10)));
+ }
+};
+
+template <unsigned digits10, class T>
+inline typename enable_if<is_arithmetic<T>, bool>::type eval_eq(const mpfi_float_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
+{
+ return a.compare(b) == 0;
+}
+template <unsigned digits10, class T>
+inline typename enable_if<is_arithmetic<T>, bool>::type eval_lt(const mpfi_float_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
+{
+ return a.compare(b) < 0;
+}
+template <unsigned digits10, class T>
+inline typename enable_if<is_arithmetic<T>, bool>::type eval_gt(const mpfi_float_backend<digits10>& a, const T& b) BOOST_NOEXCEPT
+{
+ return a.compare(b) > 0;
+}
+
+template <unsigned D1, unsigned D2>
+inline void eval_add(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
+{
+ mpfi_add(result.data(), result.data(), o.data());
+}
+template <unsigned D1, unsigned D2>
+inline void eval_subtract(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
+{
+ mpfi_sub(result.data(), result.data(), o.data());
+}
+template <unsigned D1, unsigned D2>
+inline void eval_multiply(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
+{
+ mpfi_mul(result.data(), result.data(), o.data());
+}
+template <unsigned D1, unsigned D2>
+inline void eval_divide(mpfi_float_backend<D1>& result, const mpfi_float_backend<D2>& o)
+{
+ mpfi_div(result.data(), result.data(), o.data());
+}
+template <unsigned digits10>
+inline void eval_add(mpfi_float_backend<digits10>& result, unsigned long i)
+{
+ mpfi_add_ui(result.data(), result.data(), i);
+}
+template <unsigned digits10>
+inline void eval_subtract(mpfi_float_backend<digits10>& result, unsigned long i)
+{
+ mpfi_sub_ui(result.data(), result.data(), i);
+}
+template <unsigned digits10>
+inline void eval_multiply(mpfi_float_backend<digits10>& result, unsigned long i)
+{
+ mpfi_mul_ui(result.data(), result.data(), i);
+}
+template <unsigned digits10>
+inline void eval_divide(mpfi_float_backend<digits10>& result, unsigned long i)
+{
+ mpfi_div_ui(result.data(), result.data(), i);
+}
+template <unsigned digits10>
+inline void eval_add(mpfi_float_backend<digits10>& result, long i)
+{
+ if(i > 0)
+ mpfi_add_ui(result.data(), result.data(), i);
+ else
+ mpfi_sub_ui(result.data(), result.data(), std::abs(i));
+}
+template <unsigned digits10>
+inline void eval_subtract(mpfi_float_backend<digits10>& result, long i)
+{
+ if(i > 0)
+ mpfi_sub_ui(result.data(), result.data(), i);
+ else
+ mpfi_add_ui(result.data(), result.data(), std::abs(i));
+}
+template <unsigned digits10>
+inline void eval_multiply(mpfi_float_backend<digits10>& result, long i)
+{
+ mpfi_mul_ui(result.data(), result.data(), std::abs(i));
+ if(i < 0)
+ mpfi_neg(result.data(), result.data());
+}
+template <unsigned digits10>
+inline void eval_divide(mpfi_float_backend<digits10>& result, long i)
+{
+ mpfi_div_ui(result.data(), result.data(), std::abs(i));
+ if(i < 0)
+ mpfi_neg(result.data(), result.data());
+}
+//
+// Specialised 3 arg versions of the basic operators:
+//
+template <unsigned D1, unsigned D2, unsigned D3>
+inline void eval_add(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
+{
+ mpfi_add(a.data(), x.data(), y.data());
+}
+template <unsigned D1, unsigned D2>
+inline void eval_add(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
+{
+ mpfi_add_ui(a.data(), x.data(), y);
+}
+template <unsigned D1, unsigned D2>
+inline void eval_add(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
+{
+ if(y < 0)
+ mpfi_sub_ui(a.data(), x.data(), -y);
+ else
+ mpfi_add_ui(a.data(), x.data(), y);
+}
+template <unsigned D1, unsigned D2>
+inline void eval_add(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
+{
+ mpfi_add_ui(a.data(), y.data(), x);
+}
+template <unsigned D1, unsigned D2>
+inline void eval_add(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
+{
+ if(x < 0)
+ {
+ mpfi_ui_sub(a.data(), -x, y.data());
+ mpfi_neg(a.data(), a.data());
+ }
+ else
+ mpfi_add_ui(a.data(), y.data(), x);
+}
+template <unsigned D1, unsigned D2, unsigned D3>
+inline void eval_subtract(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
+{
+ mpfi_sub(a.data(), x.data(), y.data());
+}
+template <unsigned D1, unsigned D2>
+inline void eval_subtract(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
+{
+ mpfi_sub_ui(a.data(), x.data(), y);
+}
+template <unsigned D1, unsigned D2>
+inline void eval_subtract(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
+{
+ if(y < 0)
+ mpfi_add_ui(a.data(), x.data(), -y);
+ else
+ mpfi_sub_ui(a.data(), x.data(), y);
+}
+template <unsigned D1, unsigned D2>
+inline void eval_subtract(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
+{
+ mpfi_ui_sub(a.data(), x, y.data());
+}
+template <unsigned D1, unsigned D2>
+inline void eval_subtract(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
+{
+ if(x < 0)
+ {
+ mpfi_add_ui(a.data(), y.data(), -x);
+ mpfi_neg(a.data(), a.data());
+ }
+ else
+ mpfi_ui_sub(a.data(), x, y.data());
+}
+
+template <unsigned D1, unsigned D2, unsigned D3>
+inline void eval_multiply(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
+{
+ mpfi_mul(a.data(), x.data(), y.data());
+}
+template <unsigned D1, unsigned D2>
+inline void eval_multiply(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
+{
+ mpfi_mul_ui(a.data(), x.data(), y);
+}
+template <unsigned D1, unsigned D2>
+inline void eval_multiply(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
+{
+ if(y < 0)
+ {
+ mpfi_mul_ui(a.data(), x.data(), -y);
+ a.negate();
+ }
+ else
+ mpfi_mul_ui(a.data(), x.data(), y);
+}
+template <unsigned D1, unsigned D2>
+inline void eval_multiply(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
+{
+ mpfi_mul_ui(a.data(), y.data(), x);
+}
+template <unsigned D1, unsigned D2>
+inline void eval_multiply(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
+{
+ if(x < 0)
+ {
+ mpfi_mul_ui(a.data(), y.data(), -x);
+ mpfi_neg(a.data(), a.data());
+ }
+ else
+ mpfi_mul_ui(a.data(), y.data(), x);
+}
+
+template <unsigned D1, unsigned D2, unsigned D3>
+inline void eval_divide(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, const mpfi_float_backend<D3>& y)
+{
+ mpfi_div(a.data(), x.data(), y.data());
+}
+template <unsigned D1, unsigned D2>
+inline void eval_divide(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, unsigned long y)
+{
+ mpfi_div_ui(a.data(), x.data(), y);
+}
+template <unsigned D1, unsigned D2>
+inline void eval_divide(mpfi_float_backend<D1>& a, const mpfi_float_backend<D2>& x, long y)
+{
+ if(y < 0)
+ {
+ mpfi_div_ui(a.data(), x.data(), -y);
+ a.negate();
+ }
+ else
+ mpfi_div_ui(a.data(), x.data(), y);
+}
+template <unsigned D1, unsigned D2>
+inline void eval_divide(mpfi_float_backend<D1>& a, unsigned long x, const mpfi_float_backend<D2>& y)
+{
+ mpfi_ui_div(a.data(), x, y.data());
+}
+template <unsigned D1, unsigned D2>
+inline void eval_divide(mpfi_float_backend<D1>& a, long x, const mpfi_float_backend<D2>& y)
+{
+ if(x < 0)
+ {
+ mpfi_ui_div(a.data(), -x, y.data());
+ mpfi_neg(a.data(), a.data());
+ }
+ else
+ mpfi_ui_div(a.data(), x, y.data());
+}
+
+template <unsigned digits10>
+inline bool eval_is_zero(const mpfi_float_backend<digits10>& val) BOOST_NOEXCEPT
+{
+ return 0 != mpfi_is_zero(val.data());
+}
+template <unsigned digits10>
+inline int eval_get_sign(const mpfi_float_backend<digits10>& val)
+{
+ return detail::mpfi_sgn(val.data());
+}
+
+template <unsigned digits10>
+inline void eval_convert_to(unsigned long* result, const mpfi_float_backend<digits10>& val)
+{
+ mpfr_float_backend<digits10> t;
+ mpfi_mid(t.data(), val.data());
+ eval_convert_to(result, t);
+}
+template <unsigned digits10>
+inline void eval_convert_to(long* result, const mpfi_float_backend<digits10>& val)
+{
+ mpfr_float_backend<digits10> t;
+ mpfi_mid(t.data(), val.data());
+ eval_convert_to(result, t);
+}
+#ifdef _MPFR_H_HAVE_INTMAX_T
+template <unsigned digits10>
+inline void eval_convert_to(unsigned long long* result, const mpfi_float_backend<digits10>& val)
+{
+ mpfr_float_backend<digits10> t;
+ mpfi_mid(t.data(), val.data());
+ eval_convert_to(result, t);
+}
+template <unsigned digits10>
+inline void eval_convert_to(long long* result, const mpfi_float_backend<digits10>& val)
+{
+ mpfr_float_backend<digits10> t;
+ mpfi_mid(t.data(), val.data());
+ eval_convert_to(result, t);
+}
+#endif
+template <unsigned digits10>
+inline void eval_convert_to(double* result, const mpfi_float_backend<digits10>& val) BOOST_NOEXCEPT
+{
+ *result = mpfi_get_d(val.data());
+}
+template <unsigned digits10>
+inline void eval_convert_to(long double* result, const mpfi_float_backend<digits10>& val) BOOST_NOEXCEPT
+{
+ mpfr_float_backend<digits10> t;
+ mpfi_mid(t.data(), val.data());
+ eval_convert_to(result, t);
+}
+
+template <unsigned D1, unsigned D2, mpfr_allocation_type AllocationType>
+inline void assign_components(mpfi_float_backend<D1>& result, const mpfr_float_backend<D2, AllocationType>& a, const mpfr_float_backend<D2, AllocationType>& b)
+{
+ mpfi_interv_fr(result.data(), a.data(), b.data());
+}
+
+template <unsigned Digits10, class V>
+inline typename enable_if_c<is_convertible<V, number<mpfr_float_backend<Digits10, allocate_dynamic>, et_on> >::value >::type
+ assign_components(mpfi_float_backend<Digits10>& result, const V& a, const V& b)
+{
+ number<mpfr_float_backend<Digits10, allocate_dynamic>, et_on> x(a), y(b);
+ assign_components(result, x.backend(), y.backend());
+}
+
+//
+// Native non-member operations:
+//
+template <unsigned Digits10>
+inline void eval_sqrt(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
+{
+ mpfi_sqrt(result.data(), val.data());
+}
+
+template <unsigned Digits10>
+inline void eval_abs(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
+{
+ mpfi_abs(result.data(), val.data());
+}
+
+template <unsigned Digits10>
+inline void eval_fabs(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
+{
+ mpfi_abs(result.data(), val.data());
+}
+template <unsigned Digits10>
+inline void eval_ceil(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
+{
+ mpfr_float_backend<Digits10> a, b;
+ mpfr_set(a.data(), val.left_data(), GMP_RNDN);
+ mpfr_set(b.data(), val.right_data(), GMP_RNDN);
+ eval_ceil(a, a);
+ eval_ceil(b, b);
+ if(a.compare(b) != 0)
+ {
+ BOOST_THROW_EXCEPTION(interval_error("Attempt to take the ceil of a value that straddles an integer boundary."));
+ }
+ mpfi_set_fr(result.data(), a.data());
+}
+template <unsigned Digits10>
+inline void eval_floor(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val)
+{
+ mpfr_float_backend<Digits10> a, b;
+ mpfr_set(a.data(), val.left_data(), GMP_RNDN);
+ mpfr_set(b.data(), val.right_data(), GMP_RNDN);
+ eval_floor(a, a);
+ eval_floor(b, b);
+ if(a.compare(b) != 0)
+ {
+ BOOST_THROW_EXCEPTION(interval_error("Attempt to take the floor of a value that straddles an integer boundary."));
+ }
+ mpfi_set_fr(result.data(), a.data());
+}
+template <unsigned Digits10>
+inline void eval_ldexp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val, long e)
+{
+ if(e > 0)
+ mpfi_mul_2exp(result.data(), val.data(), e);
+ else if(e < 0)
+ mpfi_div_2exp(result.data(), val.data(), -e);
+ else
+ result = val;
+}
+template <unsigned Digits10>
+inline void eval_frexp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val, int* e)
+{
+ mpfr_float_backend<Digits10> t, rt;
+ mpfi_mid(t.data(), val.data());
+ eval_frexp(rt, t, e);
+ eval_ldexp(result, val, -*e);
+}
+template <unsigned Digits10>
+inline void eval_frexp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& val, long* e)
+{
+ mpfr_float_backend<Digits10> t, rt;
+ mpfi_mid(t.data(), val.data());
+ eval_frexp(rt, t, e);
+ eval_ldexp(result, val, -*e);
+}
+
+template <unsigned Digits10>
+inline int eval_fpclassify(const mpfi_float_backend<Digits10>& val) BOOST_NOEXCEPT
+{
+ return mpfi_inf_p(val.data()) ? FP_INFINITE : mpfi_nan_p(val.data()) ? FP_NAN : mpfi_is_zero(val.data()) ? FP_ZERO : FP_NORMAL;
+}
+
+template <unsigned Digits10>
+inline void eval_pow(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& b, const mpfi_float_backend<Digits10>& e)
+{
+ mpfi_log(result.data(), b.data());
+ mpfi_mul(result.data(), result.data(), e.data());
+ mpfi_exp(result.data(), result.data());
+}
+
+template <unsigned Digits10>
+inline void eval_exp(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
+{
+ mpfi_exp(result.data(), arg.data());
+}
+
+template <unsigned Digits10>
+inline void eval_log(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
+{
+ mpfi_log(result.data(), arg.data());
+}
+
+template <unsigned Digits10>
+inline void eval_log10(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
+{
+ mpfi_log10(result.data(), arg.data());
+}
+
+template <unsigned Digits10>
+inline void eval_sin(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
+{
+ mpfi_sin(result.data(), arg.data());
+}
+
+template <unsigned Digits10>
+inline void eval_cos(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
+{
+ mpfi_cos(result.data(), arg.data());
+}
+
+template <unsigned Digits10>
+inline void eval_tan(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
+{
+ mpfi_tan(result.data(), arg.data());
+}
+
+template <unsigned Digits10>
+inline void eval_asin(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
+{
+ mpfi_asin(result.data(), arg.data());
+}
+
+template <unsigned Digits10>
+inline void eval_acos(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
+{
+ mpfi_acos(result.data(), arg.data());
+}
+
+template <unsigned Digits10>
+inline void eval_atan(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
+{
+ mpfi_atan(result.data(), arg.data());
+}
+
+template <unsigned Digits10>
+inline void eval_atan2(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg1, const mpfi_float_backend<Digits10>& arg2)
+{
+ mpfi_atan2(result.data(), arg1.data(), arg2.data());
+}
+
+template <unsigned Digits10>
+inline void eval_sinh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
+{
+ mpfi_sinh(result.data(), arg.data());
+}
+
+template <unsigned Digits10>
+inline void eval_cosh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
+{
+ mpfi_cosh(result.data(), arg.data());
+}
+
+template <unsigned Digits10>
+inline void eval_tanh(mpfi_float_backend<Digits10>& result, const mpfi_float_backend<Digits10>& arg)
+{
+ mpfi_tanh(result.data(), arg.data());
+}
+
+} // namespace backends
+
+#ifdef BOOST_NO_SFINAE_EXPR
+
+namespace detail{
+
+template<unsigned D1, unsigned D2>
+struct is_explicitly_convertible<backends::mpfi_float_backend<D1>, backends::mpfi_float_backend<D2> > : public mpl::true_ {};
+
+}
+
+#endif
+
+template<>
+struct number_category<detail::canonical<mpfi_t, backends::mpfi_float_backend<0> >::type> : public mpl::int_<number_kind_floating_point>{};
+template <unsigned Digits10>
+struct is_interval_number<backends::mpfi_float_backend<Digits10> > : public mpl::true_ {};
+
+using boost::multiprecision::backends::mpfi_float_backend;
+
+typedef number<mpfi_float_backend<50> > mpfi_float_50;
+typedef number<mpfi_float_backend<100> > mpfi_float_100;
+typedef number<mpfi_float_backend<500> > mpfi_float_500;
+typedef number<mpfi_float_backend<1000> > mpfi_float_1000;
+typedef number<mpfi_float_backend<0> > mpfi_float;
+
+//
+// Special interval specific functions:
+//
+template <unsigned Digits10, expression_template_option ExpressionTemplates>
+inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> lower(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
+{
+ number<mpfr_float_backend<Digits10> > result;
+ mpfr_set(result.backend().data(), val.backend().left_data(), GMP_RNDN);
+ return result;
+}
+
+template <unsigned Digits10, expression_template_option ExpressionTemplates>
+inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> upper(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
+{
+ number<mpfr_float_backend<Digits10> > result;
+ mpfr_set(result.backend().data(), val.backend().right_data(), GMP_RNDN);
+ return result;
+}
+
+template <unsigned Digits10, expression_template_option ExpressionTemplates>
+inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> median(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
+{
+ number<mpfr_float_backend<Digits10> > result;
+ mpfi_mid(result.backend().data(), val.backend().data());
+ return result;
+}
+
+template <unsigned Digits10, expression_template_option ExpressionTemplates>
+inline number<mpfr_float_backend<Digits10>, ExpressionTemplates> width(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& val)
+{
+ number<mpfr_float_backend<Digits10> > result;
+ mpfi_diam_abs(result.backend().data(), val.backend().data());
+ return result;
+}
+
+template <unsigned Digits10, expression_template_option ExpressionTemplates>
+inline number<mpfi_float_backend<Digits10>, ExpressionTemplates> intersect(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
+{
+ number<mpfi_float_backend<Digits10>, ExpressionTemplates> result;
+ mpfi_intersect(result.backend().data(), a.backend().data(), b.backend().data());
+ return result;
+}
+
+template <unsigned Digits10, expression_template_option ExpressionTemplates>
+inline number<mpfi_float_backend<Digits10>, ExpressionTemplates> hull(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
+{
+ number<mpfi_float_backend<Digits10>, ExpressionTemplates> result;
+ mpfi_union(result.backend().data(), a.backend().data(), b.backend().data());
+ return result;
+}
+
+template <unsigned Digits10, expression_template_option ExpressionTemplates>
+inline bool overlap(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
+{
+ return (lower(a) <= lower(b) && lower(b) <= upper(a)) ||
+ (lower(b) <= lower(a) && lower(a) <= upper(b));
+}
+
+template <unsigned Digits10, expression_template_option ExpressionTemplates1, expression_template_option ExpressionTemplates2>
+inline bool in(const number<mpfr_float_backend<Digits10>, ExpressionTemplates1>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates2>& b)
+{
+ return mpfi_is_inside_fr(a.backend().data(), b.backend().data()) != 0;
+}
+
+template <unsigned Digits10, expression_template_option ExpressionTemplates>
+inline bool zero_in(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a)
+{
+ return mpfi_has_zero(a.backend().data()) != 0;
+}
+
+template <unsigned Digits10, expression_template_option ExpressionTemplates>
+inline bool subset(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
+{
+ return mpfi_is_inside(a.backend().data(), b.backend().data()) != 0;
+}
+
+template <unsigned Digits10, expression_template_option ExpressionTemplates>
+inline bool proper_subset(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a, const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& b)
+{
+ return mpfi_is_strictly_inside(a.backend().data(), b.backend().data()) != 0;
+}
+
+template <unsigned Digits10, expression_template_option ExpressionTemplates>
+inline bool empty(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a)
+{
+ return mpfi_is_empty(a.backend().data()) != 0;
+}
+
+template <unsigned Digits10, expression_template_option ExpressionTemplates>
+inline bool singleton(const number<mpfi_float_backend<Digits10>, ExpressionTemplates>& a)
+{
+ return mpfr_cmp(a.backend().left_data(), a.backend().right_data()) == 0;
+}
+
+template <unsigned Digits10, expression_template_option ExpressionTemplates>
+struct component_type<number<mpfi_float_backend<Digits10>, ExpressionTemplates> >
+{
+ typedef number<mpfr_float_backend<Digits10>, ExpressionTemplates> type;
+};
+
+} // namespace multiprecision
+
+namespace math{
+
+namespace tools{
+
+template <>
+inline int digits<boost::multiprecision::mpfi_float>()
+{
+ return boost::multiprecision::backends::detail::get_default_precision();
+}
+template <>
+inline int digits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, boost::multiprecision::et_off> >()
+{
+ return boost::multiprecision::backends::detail::get_default_precision();
+}
+
+} // namespace tools
+
+namespace constants{ namespace detail{
+
+template <class T> struct constant_pi;
+template <class T> struct constant_ln_two;
+template <class T> struct constant_euler;
+template <class T> struct constant_catalan;
+
+template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+struct constant_pi<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
+{
+ typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type;
+ template<int N>
+ static inline result_type get(const mpl::int_<N>&)
+ {
+ result_type result;
+ mpfi_const_pi(result.backend().data());
+ return result;
+ }
+};
+template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+struct constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
+{
+ typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type;
+ template<int N>
+ static inline result_type get(const mpl::int_<N>&)
+ {
+ result_type result;
+ mpfi_const_log2(result.backend().data());
+ return result;
+ }
+};
+template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+struct constant_euler<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
+{
+ typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type;
+ template<int N>
+ static inline result_type get(const mpl::int_<N>&)
+ {
+ result_type result;
+ mpfi_const_euler(result.backend().data());
+ return result;
+ }
+};
+template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+struct constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
+{
+ typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> result_type;
+ template<int N>
+ static inline result_type get(const mpl::int_<N>&)
+ {
+ result_type result;
+ mpfi_const_catalan(result.backend().data());
+ return result;
+ }
+};
+
+}} // namespaces
+
+}} // namespaces
+
+namespace std{
+
+//
+// numeric_limits [partial] specializations for the types declared in this header:
+//
+template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >
+{
+ typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> number_type;
+public:
+ BOOST_STATIC_CONSTEXPR bool is_specialized = true;
+ static number_type (min)()
+ {
+ initializer.do_nothing();
+ static std::pair<bool, number_type> value;
+ if(!value.first)
+ {
+ value.first = true;
+ value.second = 0.5;
+ mpfi_div_2exp(value.second.backend().data(), value.second.backend().data(), -mpfr_get_emin());
+ }
+ return value.second;
+ }
+ static number_type (max)()
+ {
+ initializer.do_nothing();
+ static std::pair<bool, number_type> value;
+ if(!value.first)
+ {
+ value.first = true;
+ value.second = 0.5;
+ mpfi_mul_2exp(value.second.backend().data(), value.second.backend().data(), mpfr_get_emax());
+ }
+ return value.second;
+ }
+ BOOST_STATIC_CONSTEXPR number_type lowest()
+ {
+ return -(max)();
+ }
+ BOOST_STATIC_CONSTEXPR int digits = static_cast<int>((Digits10 * 1000L) / 301L + ((Digits10 * 1000L) % 301 ? 2 : 1));
+ BOOST_STATIC_CONSTEXPR int digits10 = Digits10;
+ // Is this really correct???
+ BOOST_STATIC_CONSTEXPR int max_digits10 = Digits10 + 2;
+ BOOST_STATIC_CONSTEXPR bool is_signed = true;
+ BOOST_STATIC_CONSTEXPR bool is_integer = false;
+ BOOST_STATIC_CONSTEXPR bool is_exact = false;
+ BOOST_STATIC_CONSTEXPR int radix = 2;
+ static number_type epsilon()
+ {
+ initializer.do_nothing();
+ static std::pair<bool, number_type> value;
+ if(!value.first)
+ {
+ value.first = true;
+ value.second = 1;
+ mpfi_div_2exp(value.second.backend().data(), value.second.backend().data(), std::numeric_limits<number_type>::digits - 1);
+ }
+ return value.second;
+ }
+ // What value should this be????
+ static number_type round_error()
+ {
+ // returns epsilon/2
+ initializer.do_nothing();
+ static std::pair<bool, number_type> value;
+ if(!value.first)
+ {
+ value.first = true;
+ value.second = 1;
+ mpfi_div_2exp(value.second.backend().data(), value.second.backend().data(), digits);
+ }
+ return value.second;
+ }
+ BOOST_STATIC_CONSTEXPR long min_exponent = MPFR_EMIN_DEFAULT;
+ BOOST_STATIC_CONSTEXPR long min_exponent10 = (MPFR_EMIN_DEFAULT / 1000) * 301L;
+ BOOST_STATIC_CONSTEXPR long max_exponent = MPFR_EMAX_DEFAULT;
+ BOOST_STATIC_CONSTEXPR long max_exponent10 = (MPFR_EMAX_DEFAULT / 1000) * 301L;
+ BOOST_STATIC_CONSTEXPR bool has_infinity = true;
+ BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = true;
+ BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
+ BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
+ BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
+ static number_type infinity()
+ {
+ initializer.do_nothing();
+ static std::pair<bool, number_type> value;
+ if(!value.first)
+ {
+ boost::multiprecision::mpfr_float_backend<Digits10> t;
+ mpfr_set_inf(t.data(), 1);
+ value.first = true;
+ mpfi_set_fr(value.second.backend().data(), t.data());
+ }
+ return value.second;
+ }
+ static number_type quiet_NaN()
+ {
+ initializer.do_nothing();
+ static std::pair<bool, number_type> value;
+ if(!value.first)
+ {
+ boost::multiprecision::mpfr_float_backend<Digits10> t;
+ mpfr_set_nan(t.data());
+ value.first = true;
+ mpfi_set_fr(value.second.backend().data(), t.data());
+ }
+ return value.second;
+ }
+ BOOST_STATIC_CONSTEXPR number_type signaling_NaN()
+ {
+ return number_type(0);
+ }
+ BOOST_STATIC_CONSTEXPR number_type denorm_min() { return number_type(0); }
+ BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
+ BOOST_STATIC_CONSTEXPR bool is_bounded = true;
+ BOOST_STATIC_CONSTEXPR bool is_modulo = false;
+ BOOST_STATIC_CONSTEXPR bool traps = true;
+ BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
+ BOOST_STATIC_CONSTEXPR float_round_style round_style = round_to_nearest;
+
+private:
+ struct data_initializer
+ {
+ data_initializer()
+ {
+ std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::epsilon();
+ std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::round_error();
+ (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::min)();
+ (std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::max)();
+ std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::infinity();
+ std::numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<digits10> > >::quiet_NaN();
+ }
+ void do_nothing()const{}
+ };
+ static const data_initializer initializer;
+};
+
+template<unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+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;
+
+#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
+
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::digits;
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::digits10;
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_digits10;
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_signed;
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_integer;
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_exact;
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::radix;
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::min_exponent;
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::min_exponent10;
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_exponent;
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST long numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::max_exponent10;
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_infinity;
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_quiet_NaN;
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_signaling_NaN;
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_denorm;
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::has_denorm_loss;
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_iec559;
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_bounded;
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::is_modulo;
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::traps;
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::tinyness_before;
+template <unsigned Digits10, boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<Digits10>, ExpressionTemplates> >::round_style;
+
+#endif
+
+
+template<boost::multiprecision::expression_template_option ExpressionTemplates>
+class numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >
+{
+ typedef boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> number_type;
+public:
+ BOOST_STATIC_CONSTEXPR bool is_specialized = false;
+ static number_type (min)() { return number_type(0); }
+ static number_type (max)() { return number_type(0); }
+ static number_type lowest() { return number_type(0); }
+ BOOST_STATIC_CONSTEXPR int digits = 0;
+ BOOST_STATIC_CONSTEXPR int digits10 = 0;
+ BOOST_STATIC_CONSTEXPR int max_digits10 = 0;
+ BOOST_STATIC_CONSTEXPR bool is_signed = false;
+ BOOST_STATIC_CONSTEXPR bool is_integer = false;
+ BOOST_STATIC_CONSTEXPR bool is_exact = false;
+ BOOST_STATIC_CONSTEXPR int radix = 0;
+ static number_type epsilon() { return number_type(0); }
+ static number_type round_error() { return number_type(0); }
+ BOOST_STATIC_CONSTEXPR int min_exponent = 0;
+ BOOST_STATIC_CONSTEXPR int min_exponent10 = 0;
+ BOOST_STATIC_CONSTEXPR int max_exponent = 0;
+ BOOST_STATIC_CONSTEXPR int max_exponent10 = 0;
+ BOOST_STATIC_CONSTEXPR bool has_infinity = false;
+ BOOST_STATIC_CONSTEXPR bool has_quiet_NaN = false;
+ BOOST_STATIC_CONSTEXPR bool has_signaling_NaN = false;
+ BOOST_STATIC_CONSTEXPR float_denorm_style has_denorm = denorm_absent;
+ BOOST_STATIC_CONSTEXPR bool has_denorm_loss = false;
+ static number_type infinity() { return number_type(0); }
+ static number_type quiet_NaN() { return number_type(0); }
+ static number_type signaling_NaN() { return number_type(0); }
+ static number_type denorm_min() { return number_type(0); }
+ BOOST_STATIC_CONSTEXPR bool is_iec559 = false;
+ BOOST_STATIC_CONSTEXPR bool is_bounded = false;
+ BOOST_STATIC_CONSTEXPR bool is_modulo = false;
+ BOOST_STATIC_CONSTEXPR bool traps = false;
+ BOOST_STATIC_CONSTEXPR bool tinyness_before = false;
+ BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero;
+};
+
+#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION
+
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::digits;
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::digits10;
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_digits10;
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_signed;
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_integer;
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_exact;
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::radix;
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::min_exponent;
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::min_exponent10;
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_exponent;
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST int numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::max_exponent10;
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_infinity;
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_quiet_NaN;
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_signaling_NaN;
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST float_denorm_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_denorm;
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::has_denorm_loss;
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_iec559;
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_bounded;
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::is_modulo;
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::traps;
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST bool numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::tinyness_before;
+template <boost::multiprecision::expression_template_option ExpressionTemplates>
+BOOST_CONSTEXPR_OR_CONST float_round_style numeric_limits<boost::multiprecision::number<boost::multiprecision::mpfi_float_backend<0>, ExpressionTemplates> >::round_style;
+
+#endif
+} // namespace std
+#endif

Modified: trunk/libs/multiprecision/config/Jamfile.v2
==============================================================================
--- trunk/libs/multiprecision/config/Jamfile.v2 (original)
+++ trunk/libs/multiprecision/config/Jamfile.v2 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -8,6 +8,7 @@
 
 local gmp_path = [ modules.peek : GMP_PATH ] ;
 local mpfr_path = [ modules.peek : MPFR_PATH ] ;
+local mpfi_path = [ modules.peek : MPFI_PATH ] ;
 local tommath_path = [ modules.peek : TOMMATH_PATH ] ;
 
 project : requirements
@@ -15,12 +16,16 @@
    <include>$(gmp_path)/mpfr
    <include>$(gmp_path)/gmpfrxx
    <include>$(mpfr_path)
+ <include>$(mpfi_path)
+ <include>$(mpfi_path)/src
    <include>$(tommath_path)
    <include>../../..
    <search>$(gmp_path)
    <search>$(mpfr_path)
    <search>$(mpfr_path)/build.vc10/lib/Win32/Debug
    <search>$(tommath_path)
+ <search>$(mpfi_path)
+ <search>$(mpfi_path)/src
    # We set these to make it easier to set up and test GMP and MPFR under Win32:
    <toolset>msvc:<runtime-link>static
    <toolset>msvc:<link>static
@@ -33,14 +38,18 @@
 
 lib gmp ;
 lib mpfr ;
+lib mpfi ;
 
 exe has_gmp : has_gmp.cpp gmp :
       <include>$(gmp_path) <include>$(gmp_path)/mpfr <include>$(gmp_path)/gmpfrxx ;
 exe has_mpfr : has_mpfr.cpp mpfr gmp :
       <include>$(mpfr_path) <include>$(gmp_path)/mpfr <include>$(gmp_path)/gmpfrxx <include>$(gmp_path) ;
+exe has_mpfi : has_mpfi.cpp mpfi mpfr gmp :
+ <include>$(mpfr_path) <include>$(gmp_path)/mpfr <include>$(gmp_path)/gmpfrxx <include>$(gmp_path) ;
 obj has_tommath : has_tommath.cpp :
       <include>$(tommath_path) ;
 
 explicit has_gmp ;
 explicit has_mpfr ;
+explicit has_mpfi ;
 explicit has_tommath ;

Added: trunk/libs/multiprecision/config/has_mpfi.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/multiprecision/config/has_mpfi.cpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -0,0 +1,55 @@
+// Copyright John Maddock 2012.
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <mpfi.h>
+#include <boost/config.hpp>
+
+#ifdef __GNUC__
+#pragma message "MPFR_VERSION_STRING=" MPFR_VERSION_STRING
+#endif
+
+#if (__GNU_MP_VERSION < 4) || ((__GNU_MP_VERSION == 4) && (__GNU_MP_VERSION_MINOR < 2))
+#error "Incompatible GMP version"
+#endif
+
+#if (MPFR_VERSION < 3)
+#error "Incompatible MPFR version"
+#endif
+
+#ifdef __GNUC__
+#pragma message "__GNU_MP_VERSION=" BOOST_STRINGIZE(__GNU_MP_VERSION)
+#pragma message "__GNU_MP_VERSION_MINOR=" BOOST_STRINGIZE(__GNU_MP_VERSION_MINOR)
+#endif
+
+#if (__GNU_MP_VERSION < 4) || ((__GNU_MP_VERSION == 4) && (__GNU_MP_VERSION_MINOR < 2))
+#error "Incompatible GMP version"
+#endif
+
+/*
+#ifdef __GNUC__
+#pragma message "MPFI_VERSION_MAJOR=" BOOST_STRINGIZE(MPFI_VERSION_MAJOR)
+#pragma message "MPFI_VERSION_MAJOR=" BOOST_STRINGIZE(MPFI_VERSION_MAJOR)
+#endif
+
+#if MPFI_VERSION_MAJOR < 1
+#error "Incompatible MPFI version"
+#endif
+#if (MPFI_VERSION_MAJOR == 1) && (MPFI_VERSION_MINOR < 5)
+#error "Incompatible MPFI version"
+#endif
+*/
+int main()
+{
+ void *(*alloc_func_ptr) (size_t);
+ void *(*realloc_func_ptr) (void *, size_t, size_t);
+ void (*free_func_ptr) (void *, size_t);
+
+ mp_get_memory_functions(&alloc_func_ptr, &realloc_func_ptr, &free_func_ptr);
+
+ mpfr_buildopt_tls_p();
+
+ return 0;
+}
+

Modified: trunk/libs/multiprecision/test/Jamfile.v2
==============================================================================
--- trunk/libs/multiprecision/test/Jamfile.v2 (original)
+++ trunk/libs/multiprecision/test/Jamfile.v2 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -9,6 +9,7 @@
 local ntl-path = [ modules.peek : NTL_PATH ] ;
 local gmp_path = [ modules.peek : GMP_PATH ] ;
 local mpfr_path = [ modules.peek : MPFR_PATH ] ;
+local mpfi_path = [ modules.peek : MPFI_PATH ] ;
 local tommath_path = [ modules.peek : TOMMATH_PATH ] ;
 
 project : requirements
@@ -16,11 +17,15 @@
    <include>$(gmp_path)/mpfr
    <include>$(gmp_path)/gmpfrxx
    <include>$(mpfr_path)
+ <include>$(mpfi_path)
+ <include>$(mpfi_path)/src
    <include>$(tommath_path)
    <include>../../..
    <search>$(gmp_path)
    <search>$(mpfr_path)
    <search>$(mpfr_path)/build.vc10/lib/Win32/Debug
+ <search>$(mpfi_path)
+ <search>$(mpfi_path)/src
    <search>$(tommath_path)
    # We set these to make it easier to set up and test GMP and MPFR under Win32:
    <toolset>msvc:<runtime-link>static
@@ -41,6 +46,7 @@
 
 lib gmp ;
 lib mpfr ;
+lib mpfi ;
 
 if $(tommath_path)
 {
@@ -94,6 +100,8 @@
 run test_arithmetic_ab_2.cpp ;
 run test_arithmetic_ab_3.cpp ;
 
+run test_arithmetic_mpfi_50.cpp mpfi mpfr gmp : : : [ check-target-builds ../config//has_mpfi : : <build>no ] ;
+
 run test_numeric_limits.cpp
         : # command line
         : # input files
@@ -171,288 +179,44 @@
               <define>TEST_CPP_INT
         : test_numeric_limits_cpp_int ;
 
-run test_exp.cpp gmp
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPF_50
- [ check-target-builds ../config//has_gmp : : <build>no ]
- : test_exp_mpf50 ;
-
-run test_log.cpp gmp
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPF_50
- [ check-target-builds ../config//has_gmp : : <build>no ]
- : test_log_mpf50 ;
-
-run test_pow.cpp gmp
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPF_50
- [ check-target-builds ../config//has_gmp : : <build>no ]
- : test_pow_mpf50 ;
-
-run test_sinh.cpp gmp
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPF_50
- [ check-target-builds ../config//has_gmp : : <build>no ]
- : test_sinh_mpf50 ;
-
-run test_cosh.cpp gmp
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPF_50
- [ check-target-builds ../config//has_gmp : : <build>no ]
- : test_cosh_mpf50 ;
-
-run test_tanh.cpp gmp
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPF_50
- [ check-target-builds ../config//has_gmp : : <build>no ]
- : test_tanh_mpf50 ;
-
-run test_exp.cpp mpfr
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPFR_50
- [ check-target-builds ../config//has_mpfr : : <build>no ]
- : test_exp_mpfr50 ;
-
-run test_log.cpp mpfr
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPFR_50
- [ check-target-builds ../config//has_mpfr : : <build>no ]
- : test_log_mpfr50 ;
-
-run test_pow.cpp mpfr
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPFR_50
- [ check-target-builds ../config//has_mpfr : : <build>no ]
- : test_pow_mpfr50 ;
-
-run test_sinh.cpp mpfr
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPFR_50
- [ check-target-builds ../config//has_mpfr : : <build>no ]
- : test_sinh_mpfr50 ;
-
-run test_cosh.cpp mpfr
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPFR_50
- [ check-target-builds ../config//has_mpfr : : <build>no ]
- : test_cosh_mpfr50 ;
-
-run test_tanh.cpp mpfr
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPFR_50
- [ check-target-builds ../config//has_mpfr : : <build>no ]
- : test_tanh_mpfr50 ;
-
-run test_exp.cpp
- : # command line
- : # input files
- : # requirements
- <define>TEST_CPP_DEC_FLOAT
- : test_exp_cpp_dec_float ;
-
-run test_sqrt.cpp
- : # command line
- : # input files
- : # requirements
- <define>TEST_CPP_DEC_FLOAT
- : test_sqrt_cpp_dec_float ;
-
-run test_log.cpp
- : # command line
- : # input files
- : # requirements
- <define>TEST_CPP_DEC_FLOAT
- : test_log_cpp_dec_float ;
-
-run test_pow.cpp
- : # command line
- : # input files
- : # requirements
- <define>TEST_CPP_DEC_FLOAT
- : test_pow_cpp_dec_float ;
-
-run test_sinh.cpp
- : # command line
- : # input files
- : # requirements
- <define>TEST_CPP_DEC_FLOAT
- : test_sinh_cpp_dec_float ;
-
-run test_cosh.cpp
- : # command line
- : # input files
- : # requirements
- <define>TEST_CPP_DEC_FLOAT
- : test_cosh_cpp_dec_float ;
-
-run test_tanh.cpp
- : # command line
- : # input files
- : # requirements
- <define>TEST_CPP_DEC_FLOAT
- : test_tanh_cpp_dec_float ;
-
-run test_sin.cpp
- : # command line
- : # input files
- : # requirements
- <define>TEST_CPP_DEC_FLOAT
- : test_sin_cpp_dec_float ;
-
-run test_sin.cpp gmp
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPF_50
- [ check-target-builds ../config//has_gmp : : <build>no ]
- : test_sin_mpf50 ;
-
-run test_sin.cpp mpfr
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPFR_50
- [ check-target-builds ../config//has_mpfr : : <build>no ]
- : test_sin_mpfr_50 ;
-
-run test_cos.cpp
- : # command line
- : # input files
- : # requirements
- <define>TEST_CPP_DEC_FLOAT
- : test_cos_cpp_dec_float ;
-
-run test_cos.cpp gmp
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPF_50
- [ check-target-builds ../config//has_gmp : : <build>no ]
- : test_cos_mpf50 ;
-
-run test_cos.cpp mpfr
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPFR_50
- [ check-target-builds ../config//has_mpfr : : <build>no ]
- : test_cos_mpfr_50 ;
-
-run test_asin.cpp
- : # command line
- : # input files
- : # requirements
- <define>TEST_CPP_DEC_FLOAT
- : test_asin_cpp_dec_float ;
-
-run test_asin.cpp gmp
+run test_numeric_limits.cpp mpfi mpfr gmp
         : # command line
         : # input files
         : # requirements
- <define>TEST_MPF_50
- [ check-target-builds ../config//has_gmp : : <build>no ]
- : test_asin_mpf50 ;
-
-run test_asin.cpp mpfr
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPFR_50
- [ check-target-builds ../config//has_mpfr : : <build>no ]
- : test_asin_mpfr_50 ;
-
-run test_acos.cpp
- : # command line
- : # input files
- : # requirements
- <define>TEST_CPP_DEC_FLOAT
- : test_acos_cpp_dec_float ;
-
-run test_acos.cpp gmp
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPF_50
- [ check-target-builds ../config//has_gmp : : <build>no ]
- : test_acos_mpf50 ;
-
-run test_acos.cpp mpfr
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPFR_50
- [ check-target-builds ../config//has_mpfr : : <build>no ]
- : test_acos_mpfr_50 ;
+ <define>TEST_MPFI_50
+ [ check-target-builds ../config//has_mpfi : : <build>no ]
+ : test_numeric_limits_mpfi_50 ;
 
-run test_atan.cpp gmp
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPF_50
- [ check-target-builds ../config//has_gmp : : <build>no ]
- : test_atan_mpf50 ;
-
-run test_atan.cpp
- : # command line
- : # input files
- : # requirements
- <define>TEST_CPP_DEC_FLOAT
- : test_atan_cpp_dec_float ;
-
-run test_atan.cpp mpfr
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPFR_50
- [ check-target-builds ../config//has_mpfr : : <build>no ]
- : test_atan_mpfr_50 ;
-
-run test_tan.cpp gmp
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPF_50
- [ check-target-builds ../config//has_gmp : : <build>no ]
- : test_tan_mpf50 ;
-
-run test_tan.cpp
- : # command line
- : # input files
- : # requirements
- <define>TEST_CPP_DEC_FLOAT
- : test_tan_cpp_dec_float ;
-
-run test_tan.cpp mpfr
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPFR_50
- [ check-target-builds ../config//has_mpfr : : <build>no ]
- : test_tan_mpfr_50 ;
+for local source in test_exp.cpp test_log.cpp test_pow.cpp test_sinh.cpp test_sqrt.cpp test_cosh.cpp test_tanh.cpp test_sin.cpp test_cos.cpp test_tan.cpp test_asin.cpp test_acos.cpp test_atan.cpp test_round.cpp test_fpclassify.cpp
+{
+ run $(source) gmp
+ : # command line
+ : # input files
+ : # requirements
+ [ check-target-builds ../config//has_gmp : : <build>no ]
+ <define>TEST_MPF_50
+ : $(source:B)_mpf50 ;
+ run $(source) mpfr gmp
+ : # command line
+ : # input files
+ : # requirements
+ [ check-target-builds ../config//has_mpfr : : <build>no ]
+ <define>TEST_MPFR_50
+ : $(source:B)_mpfr50 ;
+ run $(source) mpfi mpfr gmp
+ : # command line
+ : # input files
+ : # requirements
+ [ check-target-builds ../config//has_mpfi : : <build>no ]
+ <define>TEST_MPFI_50
+ : $(source:B)_mpfi50 ;
+ run $(source)
+ : # command line
+ : # input files
+ : # requirements
+ <define>TEST_CPP_DEC_FLOAT
+ : $(source:B)_cpp_dec_float ;
+}
 
 run test_gmp_conversions.cpp gmp
         : # command line
@@ -466,66 +230,6 @@
         : # requirements
          [ check-target-builds ../config//has_mpfr : : <build>no ] ;
 
-run test_round.cpp
- : # command line
- : # input files
- : # requirements
- <define>TEST_BACKEND
- : test_round_backend_concept ;
-
-run test_round.cpp gmp
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPF_50
- [ check-target-builds ../config//has_gmp : : <build>no ]
- : test_round_mpf50 ;
-
-run test_round.cpp mpfr
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPFR_50
- [ check-target-builds ../config//has_mpfr : : <build>no ]
- : test_round_mpfr_50 ;
-
-run test_round.cpp
- : # command line
- : # input files
- : # requirements
- <define>TEST_CPP_DEC_FLOAT
- : test_round_cpp_dec_float ;
-
-run test_fpclassify.cpp
- : # command line
- : # input files
- : # requirements
- <define>TEST_BACKEND
- : test_fpclassify_backend_concept ;
-
-run test_fpclassify.cpp gmp
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPF_50
- [ check-target-builds ../config//has_gmp : : <build>no ]
- : test_fpclassify_mpf50 ;
-
-run test_fpclassify.cpp mpfr
- : # command line
- : # input files
- : # requirements
- <define>TEST_MPFR_50
- [ check-target-builds ../config//has_mpfr : : <build>no ]
- : test_fpclassify_mpfr_50 ;
-
-run test_fpclassify.cpp
- : # command line
- : # input files
- : # requirements
- <define>TEST_CPP_DEC_FLOAT
- : test_fpclassify_cpp_dec_float ;
-
 run test_constants.cpp gmp
         : # command line
         : # input files
@@ -610,6 +314,15 @@
          [ check-target-builds ../config//has_mpfr : : <build>no ]
         : test_float_io_mpfr ;
 
+run test_float_io.cpp mpfi mpfr gmp
+ : # command line
+ : # input files
+ : # requirements
+ <define>TEST_MPFI_50
+ release # Otherwise runtime is slow
+ [ check-target-builds ../config//has_mpfi : : <build>no ]
+ : test_float_io_mpfi ;
+
 run test_int_io.cpp $(TOMMATH)
         : # command line
         : # input files

Modified: trunk/libs/multiprecision/test/test.hpp
==============================================================================
--- trunk/libs/multiprecision/test/test.hpp (original)
+++ trunk/libs/multiprecision/test/test.hpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -43,7 +43,7 @@
 }
 
 template <class T>
-typename boost::disable_if_c<boost::multiprecision::number_category<T>::value == boost::multiprecision::number_kind_integer, T>::type relative_error(T a, T b)
+typename boost::disable_if_c<(boost::multiprecision::number_category<T>::value == boost::multiprecision::number_kind_integer) || boost::multiprecision::is_interval_number<T>::value, T>::type relative_error(T a, T b)
 {
    using std::abs;
    using detail::abs;
@@ -71,6 +71,7 @@
          b = min_val;
       else if((b > -min_val) && (b < 0))
          b = -min_val;
+
       return (std::max)(abs(T((a-b)/a)), abs(T((a-b)/b))) / std::numeric_limits<T>::epsilon();
    }
 
@@ -81,6 +82,7 @@
       a = min_val;
    if(abs(b) < min_val)
       b = min_val;
+
    return (std::max)(abs(T((a-b)/a)), abs(T((a-b)/b))) / std::numeric_limits<T>::epsilon();
 }
 
@@ -92,6 +94,14 @@
    return relative_error<cast_type>(static_cast<cast_type>(a), static_cast<cast_type>(b));
 }
 
+template <class T>
+typename boost::enable_if_c<boost::multiprecision::is_interval_number<T>::value, T>::type relative_error(T a, T b)
+{
+ typename boost::multiprecision::component_type<T>::type am = median(a);
+ typename boost::multiprecision::component_type<T>::type bm = median(b);
+ return relative_error<typename boost::multiprecision::component_type<T>::type>(am, bm);
+}
+
 
 enum
 {

Modified: trunk/libs/multiprecision/test/test_acos.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_acos.cpp (original)
+++ trunk/libs/multiprecision/test/test_acos.cpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -16,11 +16,12 @@
 #include <boost/array.hpp>
 #include "test.hpp"
 
-#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ)
+#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50)
 # define TEST_MPF_50
 //# define TEST_MPF
 # define TEST_BACKEND
 # define TEST_CPP_DEC_FLOAT
+# define TEST_MPFI_50
 
 #ifdef _MSC_VER
 #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
@@ -37,6 +38,9 @@
 #if defined(TEST_MPFR_50)
 #include <boost/multiprecision/mpfr.hpp>
 #endif
+#if defined(TEST_MPFI_50)
+#include <boost/multiprecision/mpfi.hpp>
+#endif
 #ifdef TEST_BACKEND
 #include <boost/multiprecision/concepts/mp_number_archetypes.hpp>
 #endif
@@ -100,6 +104,10 @@
    test<boost::multiprecision::mpfr_float_50>();
    test<boost::multiprecision::mpfr_float_100>();
 #endif
+#ifdef TEST_MPFI_50
+ test<boost::multiprecision::mpfi_float_50>();
+ test<boost::multiprecision::mpfi_float_100>();
+#endif
 #ifdef TEST_CPP_DEC_FLOAT
    test<boost::multiprecision::cpp_dec_float_50>();
    test<boost::multiprecision::cpp_dec_float_100>();

Added: trunk/libs/multiprecision/test/test_arithmetic_mpfi_50.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/multiprecision/test/test_arithmetic_mpfi_50.cpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -0,0 +1,25 @@
+///////////////////////////////////////////////////////////////
+// Copyright 2012 John Maddock. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
+
+#ifdef _MSC_VER
+# define _SCL_SECURE_NO_WARNINGS
+#endif
+
+#include <boost/multiprecision/mpfi.hpp>
+#define TEST_MPFR
+#include "test_arithmetic.hpp"
+
+template <unsigned D>
+struct related_type<boost::multiprecision::number< boost::multiprecision::mpfi_float_backend<D> > >
+{
+ typedef boost::multiprecision::number< boost::multiprecision::mpfi_float_backend<D/2> > type;
+};
+
+int main()
+{
+ test<boost::multiprecision::mpfi_float_50>();
+ return boost::report_errors();
+}
+

Modified: trunk/libs/multiprecision/test/test_asin.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_asin.cpp (original)
+++ trunk/libs/multiprecision/test/test_asin.cpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -16,11 +16,12 @@
 #include <boost/array.hpp>
 #include "test.hpp"
 
-#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ)
+#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50)
 # define TEST_MPF_50
 //# define TEST_MPF
 # define TEST_BACKEND
 # define TEST_CPP_DEC_FLOAT
+# define TEST_MPFI_50
 
 #ifdef _MSC_VER
 #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
@@ -37,6 +38,9 @@
 #if defined(TEST_MPFR_50)
 #include <boost/multiprecision/mpfr.hpp>
 #endif
+#if defined(TEST_MPFI_50)
+#include <boost/multiprecision/mpfi.hpp>
+#endif
 #ifdef TEST_BACKEND
 #include <boost/multiprecision/concepts/mp_number_archetypes.hpp>
 #endif
@@ -96,6 +100,10 @@
    test<boost::multiprecision::mpfr_float_50>();
    test<boost::multiprecision::mpfr_float_100>();
 #endif
+#ifdef TEST_MPFI_50
+ test<boost::multiprecision::mpfi_float_50>();
+ test<boost::multiprecision::mpfi_float_100>();
+#endif
 #ifdef TEST_CPP_DEC_FLOAT
    test<boost::multiprecision::cpp_dec_float_50>();
    test<boost::multiprecision::cpp_dec_float_100>();

Modified: trunk/libs/multiprecision/test/test_atan.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_atan.cpp (original)
+++ trunk/libs/multiprecision/test/test_atan.cpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -16,11 +16,12 @@
 #include <boost/array.hpp>
 #include "test.hpp"
 
-#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ)
+#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50)
 # define TEST_MPF_50
 //# define TEST_MPF
 # define TEST_BACKEND
 # define TEST_CPP_DEC_FLOAT
+# define TEST_MPFI_50
 
 #ifdef _MSC_VER
 #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
@@ -37,6 +38,9 @@
 #if defined(TEST_MPFR_50)
 #include <boost/multiprecision/mpfr.hpp>
 #endif
+#if defined(TEST_MPFI_50)
+#include <boost/multiprecision/mpfi.hpp>
+#endif
 #ifdef TEST_BACKEND
 #include <boost/multiprecision/concepts/mp_number_archetypes.hpp>
 #endif
@@ -194,9 +198,13 @@
    err = relative_error(T(atan2(T(0), T(1))), atan2_def(T(0), T(1))).template convert_to<unsigned>();
    if(err > max_err)
       max_err = err;
- err = relative_error(T(atan2(T(0), T(-1))), atan2_def(T(0), T(-1))).template convert_to<unsigned>();
- if(err > max_err)
- max_err = err;
+ if(!boost::multiprecision::is_interval_number<T>::value)
+ {
+ // We don't test this with intervals as [-0,0] leads to strange behaviour in atan2...
+ err = relative_error(T(atan2(T(0), T(-1))), atan2_def(T(0), T(-1))).template convert_to<unsigned>();
+ if(err > max_err)
+ max_err = err;
+ }
 
    T pi;
    pi.backend() = boost::multiprecision::default_ops::get_constant_pi<typename T::backend_type>();
@@ -246,6 +254,10 @@
    test<boost::multiprecision::mpfr_float_50>();
    test<boost::multiprecision::mpfr_float_100>();
 #endif
+#ifdef TEST_MPFI_50
+ test<boost::multiprecision::mpfi_float_50>();
+ test<boost::multiprecision::mpfi_float_100>();
+#endif
 #ifdef TEST_CPP_DEC_FLOAT
    test<boost::multiprecision::cpp_dec_float_50>();
    test<boost::multiprecision::cpp_dec_float_100>();

Modified: trunk/libs/multiprecision/test/test_cos.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_cos.cpp (original)
+++ trunk/libs/multiprecision/test/test_cos.cpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -16,11 +16,12 @@
 #include <boost/array.hpp>
 #include "test.hpp"
 
-#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ)
+#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50)
 # define TEST_MPF_50
 //# define TEST_MPF
 # define TEST_BACKEND
 # define TEST_CPP_DEC_FLOAT
+# define TEST_MPFI_50
 
 #ifdef _MSC_VER
 #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
@@ -37,6 +38,9 @@
 #if defined(TEST_MPFR_50)
 #include <boost/multiprecision/mpfr.hpp>
 #endif
+#if defined(TEST_MPFI_50)
+#include <boost/multiprecision/mpfi.hpp>
+#endif
 #ifdef TEST_BACKEND
 #include <boost/multiprecision/concepts/mp_number_archetypes.hpp>
 #endif
@@ -296,6 +300,10 @@
    test<boost::multiprecision::mpfr_float_50>();
    test<boost::multiprecision::mpfr_float_100>();
 #endif
+#ifdef TEST_MPFI_50
+ test<boost::multiprecision::mpfi_float_50>();
+ test<boost::multiprecision::mpfi_float_100>();
+#endif
 #ifdef TEST_CPP_DEC_FLOAT
    test<boost::multiprecision::cpp_dec_float_50>();
    test<boost::multiprecision::cpp_dec_float_100>();

Modified: trunk/libs/multiprecision/test/test_cosh.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_cosh.cpp (original)
+++ trunk/libs/multiprecision/test/test_cosh.cpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -16,11 +16,12 @@
 #include <boost/array.hpp>
 #include "test.hpp"
 
-#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ)
+#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50)
 # define TEST_MPF_50
 //# define TEST_MPF
 # define TEST_BACKEND
 # define TEST_CPP_DEC_FLOAT
+# define TEST_MPFI_50
 
 #ifdef _MSC_VER
 #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
@@ -37,6 +38,9 @@
 #if defined(TEST_MPFR_50)
 #include <boost/multiprecision/mpfr.hpp>
 #endif
+#if defined(TEST_MPFI_50)
+#include <boost/multiprecision/mpfi.hpp>
+#endif
 #ifdef TEST_BACKEND
 #include <boost/multiprecision/concepts/mp_number_archetypes.hpp>
 #endif
@@ -138,6 +142,10 @@
    test<boost::multiprecision::mpfr_float_50>();
    test<boost::multiprecision::mpfr_float_100>();
 #endif
+#ifdef TEST_MPFI_50
+ test<boost::multiprecision::mpfi_float_50>();
+ test<boost::multiprecision::mpfi_float_100>();
+#endif
 #ifdef TEST_CPP_DEC_FLOAT
    test<boost::multiprecision::cpp_dec_float_50>();
    test<boost::multiprecision::cpp_dec_float_100>();

Modified: trunk/libs/multiprecision/test/test_exp.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_exp.cpp (original)
+++ trunk/libs/multiprecision/test/test_exp.cpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -16,11 +16,12 @@
 #include <boost/array.hpp>
 #include "test.hpp"
 
-#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ)
+#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50)
 # define TEST_MPF_50
 //# define TEST_MPF
 # define TEST_BACKEND
 # define TEST_CPP_DEC_FLOAT
+# define TEST_MPFI_50
 
 #ifdef _MSC_VER
 #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
@@ -37,6 +38,9 @@
 #if defined(TEST_MPFR_50)
 #include <boost/multiprecision/mpfr.hpp>
 #endif
+#if defined(TEST_MPFI_50)
+#include <boost/multiprecision/mpfi.hpp>
+#endif
 #ifdef TEST_BACKEND
 #include <boost/multiprecision/concepts/mp_number_archetypes.hpp>
 #endif
@@ -178,6 +182,10 @@
    test<boost::multiprecision::mpfr_float_50>();
    test<boost::multiprecision::mpfr_float_100>();
 #endif
+#ifdef TEST_MPFI_50
+ test<boost::multiprecision::mpfi_float_50>();
+ test<boost::multiprecision::mpfi_float_100>();
+#endif
 #ifdef TEST_CPP_DEC_FLOAT
    test<boost::multiprecision::cpp_dec_float_50>();
    test<boost::multiprecision::cpp_dec_float_100>();

Modified: trunk/libs/multiprecision/test/test_float_io.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_float_io.cpp (original)
+++ trunk/libs/multiprecision/test/test_float_io.cpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -9,10 +9,11 @@
 # define _SCL_SECURE_NO_WARNINGS
 #endif
 
-#if !defined(TEST_MPF_50) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50)
+#if !defined(TEST_MPF_50) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50)
 # define TEST_MPF_50
 # define TEST_CPP_DEC_FLOAT
 # define TEST_MPFR_50
+# define TEST_MPFI_50
 
 #ifdef _MSC_VER
 #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
@@ -29,6 +30,9 @@
 #if defined(TEST_MPFR_50)
 #include <boost/multiprecision/mpfr.hpp>
 #endif
+#if defined(TEST_MPFI_50)
+#include <boost/multiprecision/mpfi.hpp>
+#endif
 #ifdef TEST_CPP_DEC_FLOAT
 #include <boost/multiprecision/cpp_dec_float.hpp>
 #endif
@@ -287,6 +291,13 @@
    test_round_trip<boost::multiprecision::mpfr_float_50>();
    test_round_trip<boost::multiprecision::mpfr_float_100>();
 #endif
+#ifdef TEST_MPFI_50
+ test<boost::multiprecision::mpfr_float_50>();
+ test<boost::multiprecision::mpfr_float_100>();
+
+ test_round_trip<boost::multiprecision::mpfr_float_50>();
+ test_round_trip<boost::multiprecision::mpfr_float_100>();
+#endif
 #ifdef TEST_CPP_DEC_FLOAT
    test<boost::multiprecision::cpp_dec_float_50>();
    test<boost::multiprecision::cpp_dec_float_100>();

Modified: trunk/libs/multiprecision/test/test_fpclassify.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_fpclassify.cpp (original)
+++ trunk/libs/multiprecision/test/test_fpclassify.cpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -14,9 +14,10 @@
 #include <boost/math/special_functions/fpclassify.hpp>
 #include "test.hpp"
 
-#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ)
+#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) && !defined(TEST_MPFI_50)
 # define TEST_MPF_50
 # define TEST_MPFR_50
+# define TEST_MPFI_50
 # define TEST_BACKEND
 # define TEST_CPP_DEC_FLOAT
 
@@ -35,6 +36,9 @@
 #ifdef TEST_MPFR_50
 #include <boost/multiprecision/mpfr.hpp>
 #endif
+#ifdef TEST_MPFI_50
+#include <boost/multiprecision/mpfi.hpp>
+#endif
 #ifdef TEST_BACKEND
 #include <boost/multiprecision/concepts/mp_number_archetypes.hpp>
 #endif
@@ -309,6 +313,10 @@
    test<boost::multiprecision::mpfr_float_50>();
    test<boost::multiprecision::mpfr_float_100>();
 #endif
+#ifdef TEST_MPFI_50
+ test<boost::multiprecision::mpfi_float_50>();
+ test<boost::multiprecision::mpfi_float_100>();
+#endif
 #ifdef TEST_CPP_DEC_FLOAT
    test<boost::multiprecision::cpp_dec_float_50>();
    test<boost::multiprecision::cpp_dec_float_100>();

Modified: trunk/libs/multiprecision/test/test_log.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_log.cpp (original)
+++ trunk/libs/multiprecision/test/test_log.cpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -16,11 +16,13 @@
 #include <boost/array.hpp>
 #include "test.hpp"
 
-#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ)
+#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50)
 # define TEST_MPF_50
 //# define TEST_MPF
 # define TEST_BACKEND
 # define TEST_CPP_DEC_FLOAT
+# define TEST_MPFR_50
+# define TEST_MPFI_50
 
 #ifdef _MSC_VER
 #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
@@ -37,6 +39,9 @@
 #ifdef TEST_MPFR_50
 #include <boost/multiprecision/mpfr.hpp>
 #endif
+#ifdef TEST_MPFI_50
+#include <boost/multiprecision/mpfi.hpp>
+#endif
 #ifdef TEST_BACKEND
 #include <boost/multiprecision/concepts/mp_number_archetypes.hpp>
 #endif
@@ -206,6 +211,10 @@
    test<boost::multiprecision::mpfr_float_50>();
    test<boost::multiprecision::mpfr_float_100>();
 #endif
+#ifdef TEST_MPFI_50
+ test<boost::multiprecision::mpfi_float_50>();
+ test<boost::multiprecision::mpfi_float_100>();
+#endif
 #ifdef TEST_CPP_DEC_FLOAT
    test<boost::multiprecision::cpp_dec_float_50>();
    test<boost::multiprecision::cpp_dec_float_100>();

Added: trunk/libs/multiprecision/test/test_mpfi.cpp
==============================================================================
--- (empty file)
+++ trunk/libs/multiprecision/test/test_mpfi.cpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -0,0 +1,284 @@
+///////////////////////////////////////////////////////////////
+// Copyright 2012 John Maddock. Distributed under the Boost
+// Software License, Version 1.0. (See accompanying file
+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_
+
+#ifdef _MSC_VER
+# define _SCL_SECURE_NO_WARNINGS
+#endif
+
+#include "test.hpp"
+#include <boost/multiprecision/mpfi.hpp>
+#include <boost/multiprecision/random.hpp>
+
+using namespace boost::multiprecision;
+using namespace boost::random;
+
+void test_exp()
+{
+ std::cout << "Testing exp\n";
+
+ mpfr_float_50 val = 1.25;
+
+ for(unsigned i = 0; i < 2000; ++i)
+ {
+ mpfr_float_100 a(val);
+ mpfr_float_100 b = exp(a);
+ mpfi_float_50 in = val;
+ in = exp(in);
+ BOOST_CHECK((boost::math::isfinite)(in));
+ BOOST_CHECK(lower(in) <= b);
+ BOOST_CHECK(upper(in) >= b);
+ b = log(a);
+ in = val;
+ in = log(in);
+ BOOST_CHECK((boost::math::isfinite)(in));
+ BOOST_CHECK(lower(in) <= b);
+ BOOST_CHECK(upper(in) >= b);
+ val *= 1.01;
+ }
+ val = 1;
+ for(unsigned i = 0; i < 2000; ++i)
+ {
+ mpfr_float_100 a(val);
+ mpfr_float_100 b = exp(a);
+ mpfi_float_50 in = val;
+ in = exp(in);
+ BOOST_CHECK((boost::math::isfinite)(in));
+ BOOST_CHECK(lower(in) <= b);
+ BOOST_CHECK(upper(in) >= b);
+ b = log(a);
+ in = val;
+ in = log(in);
+ BOOST_CHECK((boost::math::isfinite)(in));
+ BOOST_CHECK(lower(in) <= b);
+ BOOST_CHECK(upper(in) >= b);
+ val /= 1.01;
+ }
+}
+
+void test_pow()
+{
+ std::cout << "Testing pow function\n";
+
+ mt19937 gen;
+ uniform_real_distribution<mpfr_float_50> dist1(0, 400);
+
+ for(unsigned i = 0; i < 5000; ++i)
+ {
+ mpfr_float_50 base, p;
+ base = dist1(gen);
+ p = dist1(gen);
+ mpfr_float_100 a, b, r;
+ a = base;
+ b = p;
+ r = pow(a, b);
+ mpfi_float_50 ai, bi, ri;
+ ai = base;
+ bi = p;
+ ri = pow(ai, bi);
+ BOOST_CHECK((boost::math::isfinite)(ri));
+ BOOST_CHECK(lower(ri) <= r);
+ BOOST_CHECK(upper(ri) >= r);
+ }
+}
+
+void test_trig()
+{
+ std::cout << "Testing trig functions\n";
+
+ mt19937 gen;
+ uniform_real_distribution<mpfr_float_50> dist1(-1.57079632679, 1.57079632679);
+ uniform_real_distribution<mpfr_float_50> dist2(-1, 1);
+
+ for(unsigned i = 0; i < 5000; ++i)
+ {
+ mpfr_float_50 val;
+ val = dist1(gen);
+ mpfr_float_100 a = val;
+ mpfr_float_100 b = sin(a);
+ mpfi_float_50 a2 = val;
+ mpfi_float_50 b2 = sin(a2);
+ BOOST_CHECK((boost::math::isfinite)(b2));
+ BOOST_CHECK(lower(b2) <= b);
+ BOOST_CHECK(upper(b2) >= b);
+ b = cos(a);
+ b2 = cos(a2);
+ BOOST_CHECK((boost::math::isfinite)(b2));
+ BOOST_CHECK(lower(b2) <= b);
+ BOOST_CHECK(upper(b2) >= b);
+ b = tan(a);
+ b2 = tan(a2);
+ BOOST_CHECK((boost::math::isfinite)(b2));
+ BOOST_CHECK(lower(b2) <= b);
+ BOOST_CHECK(upper(b2) >= b);
+ }
+ for(unsigned i = 0; i < 5000; ++i)
+ {
+ mpfr_float_50 val;
+ val = dist2(gen);
+ mpfr_float_100 a = val;
+ mpfr_float_100 b = asin(a);
+ mpfi_float_50 a2 = val;
+ mpfi_float_50 b2 = asin(a2);
+ BOOST_CHECK((boost::math::isfinite)(b2));
+ BOOST_CHECK(lower(b2) <= b);
+ BOOST_CHECK(upper(b2) >= b);
+ b = acos(a);
+ b2 = acos(a2);
+ BOOST_CHECK((boost::math::isfinite)(b2));
+ BOOST_CHECK(lower(b2) <= b);
+ BOOST_CHECK(upper(b2) >= b);
+ b = atan(a);
+ b2 = atan(a2);
+ BOOST_CHECK((boost::math::isfinite)(b2));
+ BOOST_CHECK(lower(b2) <= b);
+ BOOST_CHECK(upper(b2) >= b);
+ }
+}
+
+void test_hyp()
+{
+ std::cout << "Testing hyperbolic trig functions\n";
+
+ mt19937 gen;
+ uniform_real_distribution<mpfr_float_50> dist1(-10, 10);
+ uniform_real_distribution<mpfr_float_50> dist2(-1, 1);
+
+ for(unsigned i = 0; i < 5000; ++i)
+ {
+ mpfr_float_50 val;
+ val = dist1(gen);
+ mpfr_float_100 a = val;
+ mpfr_float_100 b = sinh(a);
+ mpfi_float_50 a2 = val;
+ mpfi_float_50 b2 = sinh(a2);
+ BOOST_CHECK((boost::math::isfinite)(b2));
+ BOOST_CHECK(lower(b2) <= b);
+ BOOST_CHECK(upper(b2) >= b);
+ b = cosh(a);
+ b2 = cosh(a2);
+ BOOST_CHECK((boost::math::isfinite)(b2));
+ BOOST_CHECK(lower(b2) <= b);
+ BOOST_CHECK(upper(b2) >= b);
+ b = tanh(a);
+ b2 = tanh(a2);
+ BOOST_CHECK((boost::math::isfinite)(b2));
+ BOOST_CHECK(lower(b2) <= b);
+ BOOST_CHECK(upper(b2) >= b);
+ }
+}
+
+void test_intervals()
+{
+ mpfi_float_50 a(1, 2);
+ mpfi_float_50 b(1.5, 2.5);
+ BOOST_CHECK_EQUAL(lower(a), 1);
+ BOOST_CHECK_EQUAL(upper(a), 2);
+ BOOST_CHECK_EQUAL(median(a), 1.5);
+ BOOST_CHECK_EQUAL(width(a), 1);
+ mpfi_float_50 r = intersect(a, b);
+ BOOST_CHECK_EQUAL(lower(r), 1.5);
+ BOOST_CHECK_EQUAL(upper(r), 2);
+ r = hull(a, b);
+ BOOST_CHECK_EQUAL(lower(r), 1);
+ BOOST_CHECK_EQUAL(upper(r), 2.5);
+ BOOST_CHECK(overlap(a, b));
+ BOOST_CHECK(in(mpfr_float_50(1.5), a));
+ BOOST_CHECK(in(mpfr_float_50(1), a));
+ BOOST_CHECK(in(mpfr_float_50(2), a));
+ BOOST_CHECK(!zero_in(a));
+ b = mpfi_float_50(1.5, 1.75);
+ BOOST_CHECK(subset(b, a));
+ BOOST_CHECK(proper_subset(b, a));
+ BOOST_CHECK(!empty(a));
+ BOOST_CHECK(!singleton(a));
+ b = mpfi_float_50(5, 6);
+ r = intersect(a, b);
+ BOOST_CHECK(empty(r));
+}
+
+#ifdef TEST_SPECIAL
+#include "math/table_type.hpp"
+#include <boost/math/special_functions.hpp>
+
+#define T mpfi_float_50
+
+typedef number<mpfi_float_backend<25> > mpfi_float_25;
+
+void test_log1p_expm1()
+{
+# include "../../math/test/log1p_expm1_data.ipp"
+
+ std::cout << std::setprecision(std::numeric_limits<mpfi_float_25>::max_digits10);
+ std::cout << "Testing log1p and expm1\n";
+
+ for(unsigned i = 0; i < log1p_expm1_data.size(); ++i)
+ {
+ mpfi_float_25 in(log1p_expm1_data[i][0]);
+ mpfi_float_25 out = boost::math::log1p(in);
+ mpfi_float_25 expected(log1p_expm1_data[i][1]);
+ if(!subset(expected, out))
+ {
+ std::cout << in << std::endl;
+ std::cout << out << std::endl;
+ std::cout << expected << std::endl;
+ BOOST_CHECK(lower(out) <= lower(expected));
+ BOOST_CHECK(upper(out) >= upper(expected));
+ }
+ out = boost::math::expm1(in);
+ expected = mpfi_float_25(log1p_expm1_data[i][2]);
+ if(!subset(expected, out))
+ {
+ std::cout << in << std::endl;
+ std::cout << out << std::endl;
+ std::cout << expected << std::endl;
+ BOOST_CHECK(lower(out) <= lower(expected));
+ BOOST_CHECK(upper(out) >= upper(expected));
+ }
+ }
+}
+
+void test_bessel()
+{
+#include "../../math/test/bessel_i_int_data.ipp"
+#include "../../math/test/bessel_i_data.ipp"
+
+ std::cout << std::setprecision(std::numeric_limits<mpfi_float_25>::max_digits10);
+ std::cout << "Testing Bessel Functions\n";
+
+ for(unsigned i = 0; i < bessel_i_int_data.size(); ++i)
+ {
+ int v = boost::lexical_cast<int>(static_cast<const char*>(bessel_i_int_data[i][0]));
+ mpfi_float_25 in(bessel_i_int_data[i][1]);
+ mpfi_float_25 out = boost::math::cyl_bessel_i(v, in);
+ mpfi_float_25 expected(bessel_i_int_data[i][2]);
+ if(!subset(expected, out))
+ {
+ std::cout << in << std::endl;
+ std::cout << out << std::endl;
+ std::cout << expected << std::endl;
+ BOOST_CHECK(lower(out) <= lower(expected));
+ BOOST_CHECK(upper(out) >= upper(expected));
+ }
+ }
+}
+
+#endif
+
+int main()
+{
+#ifdef TEST_SPECIAL
+ test_log1p_expm1();
+ test_bessel();
+#endif
+ test_intervals();
+ test_exp();
+ test_pow();
+ test_trig();
+ test_hyp();
+ return boost::report_errors();
+}
+
+
+

Modified: trunk/libs/multiprecision/test/test_numeric_limits.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_numeric_limits.cpp (original)
+++ trunk/libs/multiprecision/test/test_numeric_limits.cpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -11,7 +11,7 @@
 
 #if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && \
    !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) && \
- !defined(TEST_TOMMATH) && !defined(TEST_CPP_INT)
+ !defined(TEST_TOMMATH) && !defined(TEST_CPP_INT) && !defined(TEST_MPFI_50)
 # define TEST_MPF_50
 # define TEST_MPF
 # define TEST_BACKEND
@@ -22,6 +22,7 @@
 # define TEST_MPQ
 # define TEST_TOMMATH
 # define TEST_CPP_INT
+# define TEST_MPFI_50
 
 #ifdef _MSC_VER
 #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
@@ -44,6 +45,9 @@
 #if defined(TEST_MPFR) || defined(TEST_MPFR_50)
 #include <boost/multiprecision/mpfr.hpp>
 #endif
+#if defined(TEST_MPFI_50)
+#include <boost/multiprecision/mpfi.hpp>
+#endif
 #ifdef TEST_TOMMATH
 #include <boost/multiprecision/tommath.hpp>
 #endif
@@ -236,6 +240,10 @@
 #ifdef TEST_MPFR_50
    test<boost::multiprecision::mpfr_float_50>();
 #endif
+#ifdef TEST_MPFI_50
+ test<boost::multiprecision::mpfi_float_50>();
+ test<boost::multiprecision::mpfi_float>();
+#endif
 #ifdef TEST_TOMMATH
    test<boost::multiprecision::tom_int>();
 #endif

Modified: trunk/libs/multiprecision/test/test_pow.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_pow.cpp (original)
+++ trunk/libs/multiprecision/test/test_pow.cpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -16,12 +16,13 @@
 #include <boost/array.hpp>
 #include "test.hpp"
 
-#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ)
+#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50)
 # define TEST_MPF_50
 //# define TEST_MPF
 # define TEST_BACKEND
 # define TEST_CPP_DEC_FLOAT
 # define TEST_MPFR_50
+# define TEST_MPFI_50
 
 #ifdef _MSC_VER
 #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
@@ -38,6 +39,9 @@
 #if defined(TEST_MPFR_50)
 #include <boost/multiprecision/mpfr.hpp>
 #endif
+#if defined(TEST_MPFI_50)
+#include <boost/multiprecision/mpfi.hpp>
+#endif
 #ifdef TEST_BACKEND
 #include <boost/multiprecision/concepts/mp_number_archetypes.hpp>
 #endif
@@ -581,6 +585,10 @@
    test<boost::multiprecision::mpfr_float_50>();
    test<boost::multiprecision::mpfr_float_100>();
 #endif
+#ifdef TEST_MPFI_50
+ test<boost::multiprecision::mpfi_float_50>();
+ test<boost::multiprecision::mpfi_float_100>();
+#endif
 #ifdef TEST_CPP_DEC_FLOAT
    test<boost::multiprecision::cpp_dec_float_50>();
    test<boost::multiprecision::cpp_dec_float_100>();

Modified: trunk/libs/multiprecision/test/test_round.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_round.cpp (original)
+++ trunk/libs/multiprecision/test/test_round.cpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -15,9 +15,10 @@
 #include <boost/random/mersenne_twister.hpp>
 #include "test.hpp"
 
-#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ)
+#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50)
 # define TEST_MPF_50
 # define TEST_MPFR_50
+# define TEST_MPFI_50
 # define TEST_BACKEND
 # define TEST_CPP_DEC_FLOAT
 
@@ -36,6 +37,9 @@
 #ifdef TEST_MPFR_50
 #include <boost/multiprecision/mpfr.hpp>
 #endif
+#ifdef TEST_MPFI_50
+#include <boost/multiprecision/mpfi.hpp>
+#endif
 #ifdef TEST_BACKEND
 #include <boost/multiprecision/concepts/mp_number_archetypes.hpp>
 #endif
@@ -72,7 +76,7 @@
 }
 
 template <class T, class U>
-void check_within_half(T a, U u)
+typename boost::disable_if_c<boost::multiprecision::is_interval_number<T>::value>::type check_within_half(T a, U u)
 {
    BOOST_MATH_STD_USING
    if(fabs(a-u) > 0.5f)
@@ -88,6 +92,23 @@
          << std::left << a << u << std::endl;
    }
 }
+template <class T, class U>
+typename boost::enable_if_c<boost::multiprecision::is_interval_number<T>::value>::type check_within_half(T a, U u)
+{
+ BOOST_MATH_STD_USING
+ if(upper(T(fabs(a-u))) > 0.5f)
+ {
+ BOOST_ERROR("Rounded result differed by more than 0.5 from the original");
+ std::cerr << "Values were: " << std::setprecision(35) << std::setw(40)
+ << std::left << a << u << std::endl;
+ }
+ if((upper(T(fabs(a - u))) == 0.5f) && (fabs(static_cast<T>(u)) < fabs(a)))
+ {
+ BOOST_ERROR("Rounded result was towards zero with boost::round");
+ std::cerr << "Values were: " << std::setprecision(35) << std::setw(40)
+ << std::left << a << u << std::endl;
+ }
+}
 
 //
 // We may not have an abs overload for long long so provide a fall back:
@@ -390,6 +411,10 @@
    test<boost::multiprecision::mpfr_float_50>();
    test<boost::multiprecision::mpfr_float_100>();
 #endif
+#ifdef TEST_MPFI_50
+ test<boost::multiprecision::mpfi_float_50>();
+ test<boost::multiprecision::mpfi_float_100>();
+#endif
 #ifdef TEST_CPP_DEC_FLOAT
    test<boost::multiprecision::cpp_dec_float_50>();
    test<boost::multiprecision::cpp_dec_float_100>();

Modified: trunk/libs/multiprecision/test/test_sin.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_sin.cpp (original)
+++ trunk/libs/multiprecision/test/test_sin.cpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -16,9 +16,10 @@
 #include <boost/array.hpp>
 #include "test.hpp"
 
-#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ)
+#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50)
 # define TEST_MPF_50
-//# define TEST_MPF
+# define TEST_MPFR_50
+# define TEST_MPFI_50
 # define TEST_BACKEND
 # define TEST_CPP_DEC_FLOAT
 
@@ -37,6 +38,9 @@
 #if defined(TEST_MPFR_50)
 #include <boost/multiprecision/mpfr.hpp>
 #endif
+#if defined(TEST_MPFI_50)
+#include <boost/multiprecision/mpfi.hpp>
+#endif
 #ifdef TEST_BACKEND
 #include <boost/multiprecision/concepts/mp_number_archetypes.hpp>
 #endif
@@ -290,6 +294,10 @@
    test<boost::multiprecision::mpfr_float_50>();
    test<boost::multiprecision::mpfr_float_100>();
 #endif
+#ifdef TEST_MPFI_50
+ test<boost::multiprecision::mpfi_float_50>();
+ test<boost::multiprecision::mpfi_float_100>();
+#endif
 #ifdef TEST_CPP_DEC_FLOAT
    test<boost::multiprecision::cpp_dec_float_50>();
    test<boost::multiprecision::cpp_dec_float_100>();

Modified: trunk/libs/multiprecision/test/test_sinh.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_sinh.cpp (original)
+++ trunk/libs/multiprecision/test/test_sinh.cpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -16,9 +16,10 @@
 #include <boost/array.hpp>
 #include "test.hpp"
 
-#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ)
+#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50)
 # define TEST_MPF_50
-//# define TEST_MPF
+# define TEST_MPFR_50
+# define TEST_MPFI_50
 # define TEST_BACKEND
 # define TEST_CPP_DEC_FLOAT
 
@@ -37,6 +38,9 @@
 #if defined(TEST_MPFR_50)
 #include <boost/multiprecision/mpfr.hpp>
 #endif
+#if defined(TEST_MPFI_50)
+#include <boost/multiprecision/mpfi.hpp>
+#endif
 #ifdef TEST_BACKEND
 #include <boost/multiprecision/concepts/mp_number_archetypes.hpp>
 #endif
@@ -214,6 +218,10 @@
    test<boost::multiprecision::mpfr_float_50>();
    test<boost::multiprecision::mpfr_float_100>();
 #endif
+#ifdef TEST_MPFI_50
+ test<boost::multiprecision::mpfi_float_50>();
+ test<boost::multiprecision::mpfi_float_100>();
+#endif
 #ifdef TEST_CPP_DEC_FLOAT
    test<boost::multiprecision::cpp_dec_float_50>();
    test<boost::multiprecision::cpp_dec_float_100>();

Modified: trunk/libs/multiprecision/test/test_sqrt.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_sqrt.cpp (original)
+++ trunk/libs/multiprecision/test/test_sqrt.cpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -16,9 +16,10 @@
 #include <boost/array.hpp>
 #include "test.hpp"
 
-#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ)
+#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50)
 # define TEST_MPF_50
-//# define TEST_MPF
+# define TEST_MPFR_50
+# define TEST_MPFI_50
 # define TEST_BACKEND
 # define TEST_CPP_DEC_FLOAT
 
@@ -37,6 +38,9 @@
 #if defined(TEST_MPFR_50)
 #include <boost/multiprecision/mpfr.hpp>
 #endif
+#if defined(TEST_MPFI_50)
+#include <boost/multiprecision/mpfi.hpp>
+#endif
 #ifdef TEST_BACKEND
 #include <boost/multiprecision/concepts/mp_number_archetypes.hpp>
 #endif
@@ -183,6 +187,10 @@
    test<boost::multiprecision::mpfr_float_50>();
    test<boost::multiprecision::mpfr_float_100>();
 #endif
+#ifdef TEST_MPFI_50
+ test<boost::multiprecision::mpfi_float_50>();
+ test<boost::multiprecision::mpfi_float_100>();
+#endif
 #ifdef TEST_CPP_DEC_FLOAT
    test<boost::multiprecision::cpp_dec_float_50>();
    test<boost::multiprecision::cpp_dec_float_100>();

Modified: trunk/libs/multiprecision/test/test_tan.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_tan.cpp (original)
+++ trunk/libs/multiprecision/test/test_tan.cpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -16,9 +16,9 @@
 #include <boost/array.hpp>
 #include "test.hpp"
 
-#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ)
+#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50)
 # define TEST_MPF_50
-//# define TEST_MPF
+# define TEST_MPFI_50
 # define TEST_BACKEND
 # define TEST_CPP_DEC_FLOAT
 # define TEST_MPFR_50
@@ -38,6 +38,9 @@
 #if defined(TEST_MPFR_50)
 #include <boost/multiprecision/mpfr.hpp>
 #endif
+#if defined(TEST_MPFI_50)
+#include <boost/multiprecision/mpfi.hpp>
+#endif
 #ifdef TEST_BACKEND
 #include <boost/multiprecision/concepts/mp_number_archetypes.hpp>
 #endif
@@ -588,6 +591,10 @@
    test<boost::multiprecision::mpfr_float_50>();
    test<boost::multiprecision::mpfr_float_100>();
 #endif
+#ifdef TEST_MPFI_50
+ test<boost::multiprecision::mpfi_float_50>();
+ test<boost::multiprecision::mpfi_float_100>();
+#endif
 #ifdef TEST_CPP_DEC_FLOAT
    test<boost::multiprecision::cpp_dec_float_50>();
    test<boost::multiprecision::cpp_dec_float_100>();

Modified: trunk/libs/multiprecision/test/test_tanh.cpp
==============================================================================
--- trunk/libs/multiprecision/test/test_tanh.cpp (original)
+++ trunk/libs/multiprecision/test/test_tanh.cpp 2013-01-03 13:58:43 EST (Thu, 03 Jan 2013)
@@ -16,9 +16,10 @@
 #include <boost/array.hpp>
 #include "test.hpp"
 
-#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ)
+#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPFI_50)
 # define TEST_MPF_50
-//# define TEST_MPF
+# define TEST_MPFR_50
+# define TEST_MPFI_50
 # define TEST_BACKEND
 # define TEST_CPP_DEC_FLOAT
 
@@ -37,6 +38,9 @@
 #if defined(TEST_MPFR_50)
 #include <boost/multiprecision/mpfr.hpp>
 #endif
+#if defined(TEST_MPFI_50)
+#include <boost/multiprecision/mpfi.hpp>
+#endif
 #ifdef TEST_BACKEND
 #include <boost/multiprecision/concepts/mp_number_archetypes.hpp>
 #endif
@@ -133,6 +137,10 @@
    test<boost::multiprecision::mpfr_float_50>();
    test<boost::multiprecision::mpfr_float_100>();
 #endif
+#ifdef TEST_MPFI_50
+ test<boost::multiprecision::mpfi_float_50>();
+ test<boost::multiprecision::mpfi_float_100>();
+#endif
 #ifdef TEST_CPP_DEC_FLOAT
    test<boost::multiprecision::cpp_dec_float_50>();
    test<boost::multiprecision::cpp_dec_float_100>();


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk