#include <boost/cstdint.hpp>
#include <boost/multiprecision/detail/big_lanczos.hpp>
#include <boost/multiprecision/detail/digits.hpp>
+#include <boost/multiprecision/detail/atomic.hpp>
+#include <boost/multiprecision/traits/max_digits10.hpp>
#include <mpfr.h>
#include <cmath>
#include <algorithm>
mpfr_float_imp()
{
- mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+ mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
mpfr_set_ui(m_data, 0u, GMP_RNDN);
}
mpfr_float_imp(unsigned digits2)
mpfr_float_imp& operator=(boost::ulong_long_type i)
{
if (m_data[0]._mpfr_d == 0)
- mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+ mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
mpfr_set_uj(m_data, i, GMP_RNDN);
return *this;
}
mpfr_float_imp& operator=(boost::long_long_type i)
{
if (m_data[0]._mpfr_d == 0)
- mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+ mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
mpfr_set_sj(m_data, i, GMP_RNDN);
return *this;
}
mpfr_float_imp& operator=(boost::ulong_long_type i)
{
if (m_data[0]._mpfr_d == 0)
- mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+ mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
boost::ulong_long_type mask = ((((1uLL << (std::numeric_limits<unsigned long>::digits - 1)) - 1) << 1) | 1uLL);
unsigned shift = 0;
mpfr_t t;
- mpfr_init2(t, (std::max)(static_cast<unsigned long>(std::numeric_limits<boost::ulong_long_type>::digits), mpfr_get_prec(m_data)));
+ mpfr_init2(t, (std::max)(static_cast<mpfr_prec_t>(std::numeric_limits<boost::ulong_long_type>::digits), static_cast<mpfr_prec_t>(mpfr_get_prec(m_data))));
mpfr_set_ui(m_data, 0, GMP_RNDN);
while (i)
{
mpfr_float_imp& operator=(boost::long_long_type i)
{
if (m_data[0]._mpfr_d == 0)
- mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+ mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
bool neg = i < 0;
*this = boost::multiprecision::detail::unsigned_abs(i);
if (neg)
mpfr_float_imp& operator=(unsigned long i)
{
if (m_data[0]._mpfr_d == 0)
- mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+ mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
mpfr_set_ui(m_data, i, GMP_RNDN);
return *this;
}
mpfr_float_imp& operator=(long i)
{
if (m_data[0]._mpfr_d == 0)
- mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+ mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
mpfr_set_si(m_data, i, GMP_RNDN);
return *this;
}
mpfr_float_imp& operator=(double d)
{
if (m_data[0]._mpfr_d == 0)
- mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+ mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
mpfr_set_d(m_data, d, GMP_RNDN);
return *this;
}
mpfr_float_imp& operator=(long double a)
{
if (m_data[0]._mpfr_d == 0)
- mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+ mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
mpfr_set_ld(m_data, a, GMP_RNDN);
return *this;
}
mpfr_float_imp& operator=(const char* s)
{
if (m_data[0]._mpfr_d == 0)
- mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : get_default_precision()));
+ mpfr_init2(m_data, multiprecision::detail::digits10_2_2(digits10 ? digits10 : (unsigned)get_default_precision()));
if (mpfr_set_str(m_data, s, 10, GMP_RNDN) != 0)
{
BOOST_THROW_EXCEPTION(std::runtime_error(std::string("Unable to parse string \"") + s + std::string("\"as a valid floating point number.")));
protected:
mpfr_t m_data;
- static unsigned& get_default_precision() BOOST_NOEXCEPT
+ static boost::multiprecision::detail::precision_type& get_default_precision() BOOST_NOEXCEPT
{
- static unsigned val = BOOST_MULTIPRECISION_MPFR_DEFAULT_PRECISION;
+ static boost::multiprecision::detail::precision_type val(BOOST_MULTIPRECISION_MPFR_DEFAULT_PRECISION);
return val;
}
};
template <unsigned Digits10, mpfr_allocation_type AllocateType>
inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, int* e)
{
- long v;
- mpfr_get_d_2exp(&v, val.data(), GMP_RNDN);
+ if (mpfr_zero_p(val.data()))
+ {
+ *e = 0;
+ result = val;
+ return;
+ }
+ mp_exp_t v = mpfr_get_exp(val.data());
*e = v;
- eval_ldexp(result, val, -v);
+ if (v)
+ eval_ldexp(result, val, -v);
+ else
+ result = val;
}
template <unsigned Digits10, mpfr_allocation_type AllocateType>
inline void eval_frexp(mpfr_float_backend<Digits10, AllocateType>& result, const mpfr_float_backend<Digits10, AllocateType>& val, long* e)
{
- mpfr_get_d_2exp(e, val.data(), GMP_RNDN);
- return eval_ldexp(result, val, -*e);
+ if (mpfr_zero_p(val.data()))
+ {
+ *e = 0;
+ result = val;
+ return;
+ }
+ mp_exp_t v = mpfr_get_exp(val.data());
+ *e = v;
+ if(v)
+ eval_ldexp(result, val, -v);
+ else
+ result = val;
}
template <unsigned Digits10, mpfr_allocation_type AllocateType>
namespace tools {
+inline void set_output_precision(const boost::multiprecision::mpfr_float& val, std::ostream& os)
+{
+ os << std::setprecision(val.precision());
+}
+
template <>
inline int digits<boost::multiprecision::mpfr_float>()
#ifdef BOOST_MATH_NOEXCEPT
{
initializer()
{
- T::get(mpl::int_<N>());
+ T::get(boost::integral_constant<int, N>());
}
void force_instantiate() const {}
};
{
typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type;
template <int N>
- static inline const result_type& get(const mpl::int_<N>&)
+ static inline const result_type& get(const boost::integral_constant<int, N>&)
{
detail::mpfr_constant_initializer<constant_pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate();
static result_type result;
}
return result;
}
- static inline const result_type get(const mpl::int_<0>&)
+ static inline const result_type get(const boost::integral_constant<int, 0>&)
{
result_type result;
mpfr_const_pi(result.backend().data(), GMP_RNDN);
{
typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type;
template <int N>
- static inline const result_type& get(const mpl::int_<N>&)
+ static inline const result_type& get(const boost::integral_constant<int, N>&)
{
detail::mpfr_constant_initializer<constant_ln_two<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate();
static result_type result;
}
return result;
}
- static inline const result_type get(const mpl::int_<0>&)
+ static inline const result_type get(const boost::integral_constant<int, 0>&)
{
result_type result;
mpfr_const_log2(result.backend().data(), GMP_RNDN);
{
typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type;
template <int N>
- static inline const result_type& get(const mpl::int_<N>&)
+ static inline const result_type& get(const boost::integral_constant<int, N>&)
{
detail::mpfr_constant_initializer<constant_euler<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate();
static result_type result;
}
return result;
}
- static inline const result_type get(const mpl::int_<0>&)
+ static inline const result_type get(const boost::integral_constant<int, 0>&)
{
result_type result;
mpfr_const_euler(result.backend().data(), GMP_RNDN);
{
typedef boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result_type;
template <int N>
- static inline const result_type& get(const mpl::int_<N>&)
+ static inline const result_type& get(const boost::integral_constant<int, N>&)
{
detail::mpfr_constant_initializer<constant_catalan<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >, N>::force_instantiate();
static result_type result;
}
return result;
}
- static inline const result_type get(const mpl::int_<0>&)
+ static inline const result_type get(const boost::integral_constant<int, 0>&)
{
result_type result;
mpfr_const_catalan(result.backend().data(), GMP_RNDN);
{
typedef boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result_type;
template <int N>
- static inline const result_type& get(const mpl::int_<N>&)
+ static inline const result_type& get(const boost::integral_constant<int, N>&)
{
detail::mpfr_constant_initializer<constant_pi<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >, N>::force_instantiate();
static result_type result;
}
return result;
}
- static inline const result_type get(const mpl::int_<0>&)
+ static inline const result_type get(const boost::integral_constant<int, 0>&)
{
result_type result;
mpfr_const_pi(result.backend().value().data(), GMP_RNDN);
{
typedef boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result_type;
template <int N>
- static inline const result_type& get(const mpl::int_<N>&)
+ static inline const result_type& get(const boost::integral_constant<int, N>&)
{
detail::mpfr_constant_initializer<constant_ln_two<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >, N>::force_instantiate();
static result_type result;
}
return result;
}
- static inline const result_type get(const mpl::int_<0>&)
+ static inline const result_type get(const boost::integral_constant<int, 0>&)
{
result_type result;
mpfr_const_log2(result.backend().value().data(), GMP_RNDN);
{
typedef boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result_type;
template <int N>
- static inline const result_type& get(const mpl::int_<N>&)
+ static inline const result_type& get(const boost::integral_constant<int, N>&)
{
detail::mpfr_constant_initializer<constant_euler<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >, N>::force_instantiate();
static result_type result;
}
return result;
}
- static inline const result_type get(const mpl::int_<0>&)
+ static inline const result_type get(const boost::integral_constant<int, 0>&)
{
result_type result;
mpfr_const_euler(result.backend().value().data(), GMP_RNDN);
{
typedef boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> result_type;
template <int N>
- static inline const result_type& get(const mpl::int_<N>&)
+ static inline const result_type& get(const boost::integral_constant<int, N>&)
{
detail::mpfr_constant_initializer<constant_catalan<boost::multiprecision::number<boost::multiprecision::debug_adaptor<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType> >, ExpressionTemplates> >, N>::force_instantiate();
static result_type result;
}
return result;
}
- static inline const result_type get(const mpl::int_<0>&)
+ static inline const result_type get(const boost::integral_constant<int, 0>&)
{
result_type result;
mpfr_const_catalan(result.backend().value().data(), GMP_RNDN);
{
t = -t;
}
- result = log(boost::math::constants::pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >()) - lgamma(arg, 0, pol) - log(t);
+ result = boost::multiprecision::log(boost::math::constants::pi<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >()) - lgamma(arg, 0, pol) - boost::multiprecision::log(t);
if (sign)
{
boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> phase = 1 - arg;
boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
mpfr_log1p(result.backend().data(), arg.backend().data(), GMP_RNDN);
if (mpfr_inf_p(result.backend().data()))
- return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("log1p<%1%>(%1%)", 0, pol);
+ return (arg == -1 ? -1 : 1) * policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("log1p<%1%>(%1%)", 0, pol);
if (mpfr_nan_p(result.backend().data()))
return policies::raise_evaluation_error("log1p<%1%>(%1%)", "Unknown error, result is a NaN", result, pol);
return result;
return log1p(arg, policies::policy<>());
}
+template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates, class Policy>
+inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> rsqrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg, const Policy& pol)
+{
+ boost::multiprecision::detail::scoped_default_precision<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> > precision_guard(arg);
+
+ boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> result;
+ mpfr_rec_sqrt(result.backend().data(), arg.backend().data(), GMP_RNDN);
+ if (mpfr_inf_p(result.backend().data()))
+ return policies::raise_overflow_error<boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> >("rsqrt<%1%>(%1%)", 0, pol);
+ if (mpfr_nan_p(result.backend().data()))
+ return policies::raise_evaluation_error("rsqrt<%1%>(%1%)", "Negative argument, result is a NaN", result, pol);
+ return result;
+}
+template <unsigned Digits10, boost::multiprecision::mpfr_allocation_type AllocateType, boost::multiprecision::expression_template_option ExpressionTemplates>
+inline boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates> rsqrt BOOST_PREVENT_MACRO_SUBSTITUTION(const boost::multiprecision::number<boost::multiprecision::mpfr_float_backend<Digits10, AllocateType>, ExpressionTemplates>& arg)
+{
+ return rsqrt(arg, policies::policy<>());
+}
+
} // namespace math
} // namespace boost
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 + 3;
+ BOOST_STATIC_CONSTEXPR int max_digits10 = boost::multiprecision::detail::calc_max_digits10<digits>::value;
BOOST_STATIC_CONSTEXPR bool is_signed = true;
BOOST_STATIC_CONSTEXPR bool is_integer = false;
BOOST_STATIC_CONSTEXPR bool is_exact = false;