mirror of
https://github.com/boostorg/multiprecision.git
synced 2026-02-21 03:02:18 +00:00
Giant file and directory rename: changed directory name from math to multiprecision and updated code to match.
[SVN r74582]
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -1,147 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////
|
||||
// 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_
|
||||
|
||||
#ifndef BOOST_MATH_ARITH_BACKEND_HPP
|
||||
#define BOOST_MATH_ARITH_BACKEND_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/math/big_number.hpp>
|
||||
|
||||
namespace boost{
|
||||
namespace math{
|
||||
|
||||
template <class Arithmetic>
|
||||
struct arithmetic_backend
|
||||
{
|
||||
typedef mpl::list<long long> signed_types;
|
||||
typedef mpl::list<unsigned long long> unsigned_types;
|
||||
typedef mpl::list<long double> real_types;
|
||||
|
||||
arithmetic_backend(){}
|
||||
arithmetic_backend(const arithmetic_backend& o)
|
||||
{
|
||||
m_value = o.m_value;
|
||||
}
|
||||
arithmetic_backend(const Arithmetic& o) : m_value(o) {}
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
arithmetic_backend(arithmetic_backend&& o) : m_value(o.m_value) {}
|
||||
arithmetic_backend(Arithmetic&& o) : m_value(o) {}
|
||||
#endif
|
||||
arithmetic_backend& operator = (const arithmetic_backend& o)
|
||||
{
|
||||
m_value = o.m_value;
|
||||
return *this;
|
||||
}
|
||||
arithmetic_backend& operator = (boost::uintmax_t i)
|
||||
{
|
||||
m_value = i;
|
||||
return *this;
|
||||
}
|
||||
arithmetic_backend& operator = (boost::intmax_t i)
|
||||
{
|
||||
m_value = i;
|
||||
return *this;
|
||||
}
|
||||
arithmetic_backend& operator = (long double d)
|
||||
{
|
||||
m_value = d;
|
||||
return *this;
|
||||
}
|
||||
arithmetic_backend& operator = (const char* s)
|
||||
{
|
||||
m_value = boost::lexical_cast<double>(s);
|
||||
return *this;
|
||||
}
|
||||
void swap(arithmetic_backend& o)
|
||||
{
|
||||
std::swap(m_value, o.m_value);
|
||||
}
|
||||
std::string str(unsigned digits, bool scientific)const
|
||||
{
|
||||
return boost::lexical_cast<std::string>(m_value);
|
||||
}
|
||||
void negate()
|
||||
{
|
||||
m_value = -m_value;
|
||||
}
|
||||
int compare(const arithmetic_backend& o)const
|
||||
{
|
||||
return m_value > o.m_value ? 1 : (m_value < o.m_value ? -1 : 0);
|
||||
}
|
||||
int compare(boost::intmax_t i)const
|
||||
{
|
||||
return m_value > i ? 1 : (m_value < i ? -1 : 0);
|
||||
}
|
||||
int compare(boost::uintmax_t i)const
|
||||
{
|
||||
return m_value > i ? 1 : (m_value < i ? -1 : 0);
|
||||
}
|
||||
int compare(long double d)const
|
||||
{
|
||||
return m_value > d ? 1 : (m_value < d ? -1 : 0);
|
||||
}
|
||||
Arithmetic& data() { return m_value; }
|
||||
const Arithmetic& data()const { return m_value; }
|
||||
private:
|
||||
Arithmetic m_value;
|
||||
};
|
||||
|
||||
template <class Arithmetic>
|
||||
inline void add(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
|
||||
{
|
||||
result.data() += o.data();
|
||||
}
|
||||
template <class Arithmetic>
|
||||
inline void subtract(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
|
||||
{
|
||||
result.data() -= o.data();
|
||||
}
|
||||
template <class Arithmetic>
|
||||
inline void multiply(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
|
||||
{
|
||||
result.data() *= o.data();
|
||||
}
|
||||
template <class Arithmetic>
|
||||
inline void divide(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
|
||||
{
|
||||
result.data() /= o.data();
|
||||
}
|
||||
|
||||
}} // namespaces
|
||||
|
||||
|
||||
namespace std{
|
||||
|
||||
#ifdef BOOST_NO_NOEXCEPT
|
||||
# define noexcept
|
||||
#endif
|
||||
|
||||
template <class Arithmetic>
|
||||
class numeric_limits<boost::math::big_number<boost::math::arithmetic_backend<Arithmetic> > > : public std::numeric_limits<Arithmetic>
|
||||
{
|
||||
typedef std::numeric_limits<Arithmetic> base_type;
|
||||
typedef boost::math::big_number<boost::math::arithmetic_backend<Arithmetic> > number_type;
|
||||
public:
|
||||
BOOST_STATIC_CONSTEXPR number_type (min)() noexcept { return (base_type::min)(); }
|
||||
BOOST_STATIC_CONSTEXPR number_type (max)() noexcept { return (base_type::max)(); }
|
||||
BOOST_STATIC_CONSTEXPR number_type lowest() noexcept { return -(max)(); }
|
||||
BOOST_STATIC_CONSTEXPR number_type epsilon() noexcept { return base_type::epsilon(); }
|
||||
BOOST_STATIC_CONSTEXPR number_type round_error() noexcept { return epsilon() / 2; }
|
||||
BOOST_STATIC_CONSTEXPR number_type infinity() noexcept { return base_type::infinity(); }
|
||||
BOOST_STATIC_CONSTEXPR number_type quiet_NaN() noexcept { return base_type::quiet_NaN(); }
|
||||
BOOST_STATIC_CONSTEXPR number_type signaling_NaN() noexcept { return base_type::signaling_NaN(); }
|
||||
BOOST_STATIC_CONSTEXPR number_type denorm_min() noexcept { return base_type::denorm_min(); }
|
||||
};
|
||||
|
||||
#ifdef BOOST_NO_NOEXCEPT
|
||||
# undef noexcept
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,983 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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_BIG_NUM_BASE_HPP
|
||||
#define BOOST_MATH_BIG_NUM_BASE_HPP
|
||||
|
||||
#include <limits>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
template <class Backend>
|
||||
class big_number;
|
||||
|
||||
namespace detail{
|
||||
|
||||
// Forward-declare an expression wrapper
|
||||
template<class tag, class Arg1 = void, class Arg2 = void, class Arg3 = void>
|
||||
struct big_number_exp;
|
||||
|
||||
template <int b>
|
||||
struct has_enough_bits
|
||||
{
|
||||
template <class T>
|
||||
struct type : public mpl::bool_<std::numeric_limits<T>::digits >= b>{};
|
||||
};
|
||||
|
||||
template <class Val, class Backend, class Tag>
|
||||
struct canonical_imp
|
||||
{
|
||||
typedef Val type;
|
||||
};
|
||||
template <class Val, class Backend>
|
||||
struct canonical_imp<Val, Backend, mpl::int_<0> >
|
||||
{
|
||||
typedef typename has_enough_bits<std::numeric_limits<Val>::digits>::template type<mpl::_> pred_type;
|
||||
typedef typename mpl::find_if<
|
||||
typename Backend::signed_types,
|
||||
pred_type
|
||||
>::type iter_type;
|
||||
typedef typename mpl::deref<iter_type>::type type;
|
||||
};
|
||||
template <class Val, class Backend>
|
||||
struct canonical_imp<Val, Backend, mpl::int_<1> >
|
||||
{
|
||||
typedef typename has_enough_bits<std::numeric_limits<Val>::digits>::template type<mpl::_> pred_type;
|
||||
typedef typename mpl::find_if<
|
||||
typename Backend::unsigned_types,
|
||||
pred_type
|
||||
>::type iter_type;
|
||||
typedef typename mpl::deref<iter_type>::type type;
|
||||
};
|
||||
template <class Val, class Backend>
|
||||
struct canonical_imp<Val, Backend, mpl::int_<2> >
|
||||
{
|
||||
typedef typename has_enough_bits<std::numeric_limits<Val>::digits>::template type<mpl::_> pred_type;
|
||||
typedef typename mpl::find_if<
|
||||
typename Backend::real_types,
|
||||
pred_type
|
||||
>::type iter_type;
|
||||
typedef typename mpl::deref<iter_type>::type type;
|
||||
};
|
||||
template <class Val, class Backend>
|
||||
struct canonical_imp<Val, Backend, mpl::int_<3> >
|
||||
{
|
||||
typedef const char* type;
|
||||
};
|
||||
|
||||
template <class Val, class Backend>
|
||||
struct canonical
|
||||
{
|
||||
typedef typename mpl::if_<
|
||||
is_signed<Val>,
|
||||
mpl::int_<0>,
|
||||
typename mpl::if_<
|
||||
is_unsigned<Val>,
|
||||
mpl::int_<1>,
|
||||
typename mpl::if_<
|
||||
is_floating_point<Val>,
|
||||
mpl::int_<2>,
|
||||
typename mpl::if_<
|
||||
mpl::or_<
|
||||
is_convertible<Val, const char*>,
|
||||
is_same<Val, std::string>
|
||||
>,
|
||||
mpl::int_<3>,
|
||||
mpl::int_<4>
|
||||
>::type
|
||||
>::type
|
||||
>::type
|
||||
>::type tag_type;
|
||||
|
||||
typedef typename canonical_imp<Val, Backend, tag_type>::type type;
|
||||
};
|
||||
|
||||
struct terminal{};
|
||||
struct negate{};
|
||||
struct plus{};
|
||||
struct minus{};
|
||||
struct multiplies{};
|
||||
struct divides{};
|
||||
struct modulus{};
|
||||
struct shift_left{};
|
||||
struct shift_right{};
|
||||
struct bitwise_and{};
|
||||
struct bitwise_or{};
|
||||
struct bitwise_xor{};
|
||||
struct bitwise_complement{};
|
||||
struct add_immediates{};
|
||||
struct subtract_immediates{};
|
||||
struct multiply_immediates{};
|
||||
struct divide_immediates{};
|
||||
struct modulus_immediates{};
|
||||
struct bitwise_and_immediates{};
|
||||
struct bitwise_or_immediates{};
|
||||
struct bitwise_xor_immediates{};
|
||||
struct complement_immediates{};
|
||||
struct function{};
|
||||
|
||||
template <class T>
|
||||
struct backend_type;
|
||||
|
||||
template <class T>
|
||||
struct backend_type<big_number<T> >
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <class tag, class A1, class A2, class A3>
|
||||
struct backend_type<big_number_exp<tag, A1, A2, A3> >
|
||||
{
|
||||
typedef typename backend_type<typename big_number_exp<tag, A1, A2, A3>::result_type>::type type;
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
struct is_big_number : public mpl::false_{};
|
||||
template <class T>
|
||||
struct is_big_number<boost::math::big_number<T> > : public mpl::true_{};
|
||||
template <class T>
|
||||
struct is_big_number_exp : public mpl::false_{};
|
||||
template <class Tag, class Arg1, class Arg2, class Arg3>
|
||||
struct is_big_number_exp<boost::math::detail::big_number_exp<Tag, Arg1, Arg2, Arg3> > : public mpl::true_{};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct combine_expression;
|
||||
|
||||
template <class T1, class T2>
|
||||
struct combine_expression<big_number<T1>, T2>
|
||||
{
|
||||
typedef big_number<T1> type;
|
||||
};
|
||||
|
||||
template <class T1, class T2>
|
||||
struct combine_expression<T1, big_number<T2> >
|
||||
{
|
||||
typedef big_number<T2> type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct combine_expression<big_number<T>, big_number<T> >
|
||||
{
|
||||
typedef big_number<T> type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct arg_type
|
||||
{
|
||||
typedef big_number_exp<terminal, T> type;
|
||||
};
|
||||
|
||||
template <class Tag, class Arg1, class Arg2, class Arg3>
|
||||
struct arg_type<big_number_exp<Tag, Arg1, Arg2, Arg3> >
|
||||
{
|
||||
typedef big_number_exp<Tag, Arg1, Arg2, Arg3> type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct unmentionable
|
||||
{
|
||||
static void proc(){}
|
||||
};
|
||||
|
||||
typedef void (*unmentionable_type)();
|
||||
|
||||
template <class T>
|
||||
struct big_number_exp_storage
|
||||
{
|
||||
typedef const T& type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct big_number_exp_storage<T*>
|
||||
{
|
||||
typedef T* type;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct big_number_exp_storage<const T*>
|
||||
{
|
||||
typedef const T* type;
|
||||
};
|
||||
|
||||
template <class tag, class A1, class A2, class A3>
|
||||
struct big_number_exp_storage<big_number_exp<tag, A1, A2, A3> >
|
||||
{
|
||||
typedef big_number_exp<tag, A1, A2, A3> type;
|
||||
};
|
||||
|
||||
template<class tag, class Arg1>
|
||||
struct big_number_exp<tag, Arg1, void, void>
|
||||
{
|
||||
typedef mpl::int_<1> arity;
|
||||
typedef typename arg_type<Arg1>::type left_type;
|
||||
typedef typename left_type::result_type result_type;
|
||||
typedef tag tag_type;
|
||||
|
||||
big_number_exp(const Arg1& a) : arg(a) {}
|
||||
|
||||
left_type left()const { return arg; }
|
||||
|
||||
const Arg1& left_ref()const{ return arg; }
|
||||
|
||||
static const unsigned depth = left_type::depth + 1;
|
||||
|
||||
operator unmentionable_type()const
|
||||
{
|
||||
result_type r(*this);
|
||||
return r ? &unmentionable<void>::proc : 0;
|
||||
}
|
||||
|
||||
private:
|
||||
typename big_number_exp_storage<Arg1>::type arg;
|
||||
};
|
||||
|
||||
template<class Arg1>
|
||||
struct big_number_exp<terminal, Arg1, void, void>
|
||||
{
|
||||
typedef mpl::int_<0> arity;
|
||||
typedef Arg1 result_type;
|
||||
typedef terminal tag_type;
|
||||
|
||||
big_number_exp(const Arg1& a) : arg(a) {}
|
||||
|
||||
const Arg1& value()const { return arg; }
|
||||
|
||||
static const unsigned depth = 0;
|
||||
|
||||
operator unmentionable_type()const
|
||||
{
|
||||
return arg ? &unmentionable<void>::proc : 0;
|
||||
}
|
||||
|
||||
private:
|
||||
typename big_number_exp_storage<Arg1>::type arg;
|
||||
};
|
||||
|
||||
template <class tag, class Arg1, class Arg2>
|
||||
struct big_number_exp<tag, Arg1, Arg2, void>
|
||||
{
|
||||
typedef mpl::int_<2> arity;
|
||||
typedef typename arg_type<Arg1>::type left_type;
|
||||
typedef typename arg_type<Arg2>::type right_type;
|
||||
typedef typename left_type::result_type left_result_type;
|
||||
typedef typename right_type::result_type right_result_type;
|
||||
typedef typename combine_expression<left_result_type, right_result_type>::type result_type;
|
||||
typedef tag tag_type;
|
||||
|
||||
big_number_exp(const Arg1& a1, const Arg2& a2) : arg1(a1), arg2(a2) {}
|
||||
|
||||
left_type left()const { return arg1; }
|
||||
right_type right()const { return arg2; }
|
||||
const Arg1& left_ref()const{ return arg1; }
|
||||
const Arg2& right_ref()const{ return arg2; }
|
||||
|
||||
operator unmentionable_type()const
|
||||
{
|
||||
result_type r(*this);
|
||||
return r ? &unmentionable<void>::proc : 0;
|
||||
}
|
||||
|
||||
static const unsigned left_depth = left_type::depth + 1;
|
||||
static const unsigned right_depth = right_type::depth + 1;
|
||||
static const unsigned depth = left_depth > right_depth ? left_depth : right_depth;
|
||||
private:
|
||||
typename big_number_exp_storage<Arg1>::type arg1;
|
||||
typename big_number_exp_storage<Arg2>::type arg2;
|
||||
};
|
||||
|
||||
template <class tag, class Arg1, class Arg2, class Arg3>
|
||||
struct big_number_exp
|
||||
{
|
||||
typedef mpl::int_<3> arity;
|
||||
typedef typename arg_type<Arg1>::type left_type;
|
||||
typedef typename arg_type<Arg2>::type middle_type;
|
||||
typedef typename arg_type<Arg3>::type right_type;
|
||||
typedef typename left_type::result_type left_result_type;
|
||||
typedef typename middle_type::result_type middle_result_type;
|
||||
typedef typename right_type::result_type right_result_type;
|
||||
typedef typename combine_expression<
|
||||
left_result_type,
|
||||
typename combine_expression<right_result_type, middle_result_type>::type
|
||||
>::type result_type;
|
||||
typedef tag tag_type;
|
||||
|
||||
big_number_exp(const Arg1& a1, const Arg2& a2, const Arg3& a3) : arg1(a1), arg2(a2), arg3(a3) {}
|
||||
|
||||
left_type left()const { return arg1; }
|
||||
middle_type middle()const { return arg2; }
|
||||
right_type right()const { return arg3; }
|
||||
const Arg1& left_ref()const{ return arg1; }
|
||||
const Arg2& middle_ref()const{ return arg2; }
|
||||
const Arg3& right_ref()const{ return arg3; }
|
||||
|
||||
operator unmentionable_type()const
|
||||
{
|
||||
result_type r(*this);
|
||||
return r ? &unmentionable<void>::proc : 0;
|
||||
}
|
||||
|
||||
static const unsigned left_depth = left_type::depth + 1;
|
||||
static const unsigned middle_depth = middle_type::depth + 1;
|
||||
static const unsigned right_depth = right_type::depth + 1;
|
||||
static const unsigned depth = left_depth > right_depth ? (left_depth > middle_depth ? left_depth : middle_depth) : (right_depth > middle_depth ? right_depth : middle_depth);
|
||||
private:
|
||||
typename big_number_exp_storage<Arg1>::type arg1;
|
||||
typename big_number_exp_storage<Arg2>::type arg2;
|
||||
typename big_number_exp_storage<Arg3>::type arg3;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
//
|
||||
// Non-member operators for big_number:
|
||||
//
|
||||
// Unary operators first:
|
||||
//
|
||||
template <class B>
|
||||
inline const big_number<B>& operator + (const big_number<B>& v) { return v; }
|
||||
template <class tag, class Arg1, class Arg2, class Arg3>
|
||||
inline const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& operator + (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& v) { return v; }
|
||||
template <class B>
|
||||
inline detail::big_number_exp<detail::negate, big_number<B> > operator - (const big_number<B>& v) { return v; }
|
||||
template <class tag, class Arg1, class Arg2, class Arg3>
|
||||
inline detail::big_number_exp<detail::negate, detail::big_number_exp<tag, Arg1, Arg2, Arg3> > operator - (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& v) { return v; }
|
||||
template <class B>
|
||||
inline detail::big_number_exp<detail::complement_immediates, big_number<B> > operator ~ (const big_number<B>& v) { return v; }
|
||||
template <class tag, class Arg1, class Arg2, class Arg3>
|
||||
inline detail::big_number_exp<detail::bitwise_complement, detail::big_number_exp<tag, Arg1, Arg2, Arg3> > operator ~ (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& v) { return v; }
|
||||
//
|
||||
// Then addition:
|
||||
//
|
||||
template <class B>
|
||||
inline detail::big_number_exp<detail::add_immediates, big_number<B>, big_number<B> >
|
||||
operator + (const big_number<B>& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::add_immediates, big_number<B>, big_number<B> >(a, b);
|
||||
}
|
||||
template <class B, class V>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::add_immediates, big_number<B>, V > >::type
|
||||
operator + (const big_number<B>& a, const V& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::add_immediates, big_number<B>, V >(a, b);
|
||||
}
|
||||
template <class V, class B>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::add_immediates, V, big_number<B> > >::type
|
||||
operator + (const V& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::add_immediates, V, big_number<B> >(a, b);
|
||||
}
|
||||
template <class B, class tag, class Arg1, class Arg2, class Arg3>
|
||||
inline detail::big_number_exp<detail::plus, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >
|
||||
operator + (const big_number<B>& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::plus, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class B>
|
||||
inline detail::big_number_exp<detail::plus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >
|
||||
operator + (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::plus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
|
||||
inline detail::big_number_exp<detail::plus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >
|
||||
operator + (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::plus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class V>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::plus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V > >::type
|
||||
operator + (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::plus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
|
||||
}
|
||||
template <class V, class tag, class Arg1, class Arg2, class Arg3>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::plus, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> > >::type
|
||||
operator + (const V& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::plus, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
|
||||
}
|
||||
//
|
||||
// Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
|
||||
//
|
||||
template <class B, class Arg1, class Arg2, class Arg3>
|
||||
inline detail::big_number_exp<detail::minus, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >
|
||||
operator + (const big_number<B>& a, const detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::minus, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(a, b.left_ref());
|
||||
}
|
||||
template <class Arg1, class Arg2, class Arg3, class B>
|
||||
inline detail::big_number_exp<detail::minus, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >
|
||||
operator + (const detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::minus, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(b, a.left_ref());
|
||||
}
|
||||
template <class B>
|
||||
inline detail::big_number_exp<detail::subtract_immediates, big_number<B>, big_number<B> >
|
||||
operator + (const big_number<B>& a, const detail::big_number_exp<detail::negate, big_number<B> >& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::subtract_immediates, big_number<B>, big_number<B> >(a, b.left_ref());
|
||||
}
|
||||
template <class B>
|
||||
inline detail::big_number_exp<detail::subtract_immediates, big_number<B>, big_number<B> >
|
||||
operator + (const detail::big_number_exp<detail::negate, big_number<B> >& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::subtract_immediates, big_number<B>, big_number<B> >(b, a.left_ref());
|
||||
}
|
||||
template <class B, class V>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::subtract_immediates, big_number<B>, V > >::type
|
||||
operator + (const detail::big_number_exp<detail::negate, big_number<B> >& a, const V& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::subtract_immediates, V, big_number<B> >(b, a.left_ref());
|
||||
}
|
||||
template <class V, class B>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::subtract_immediates, V, big_number<B> > >::type
|
||||
operator + (const V& a, const detail::big_number_exp<detail::negate, big_number<B> >& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::subtract_immediates, big_number<B>, big_number<B> >(a, b.left_ref());
|
||||
}
|
||||
//
|
||||
// Subtraction:
|
||||
//
|
||||
template <class B>
|
||||
inline detail::big_number_exp<detail::subtract_immediates, big_number<B>, big_number<B> >
|
||||
operator - (const big_number<B>& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::subtract_immediates, big_number<B>, big_number<B> >(a, b);
|
||||
}
|
||||
template <class B, class V>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::subtract_immediates, big_number<B>, V > >::type
|
||||
operator - (const big_number<B>& a, const V& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::subtract_immediates, big_number<B>, V >(a, b);
|
||||
}
|
||||
template <class V, class B>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::subtract_immediates, V, big_number<B> > >::type
|
||||
operator - (const V& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::subtract_immediates, V, big_number<B> >(a, b);
|
||||
}
|
||||
template <class B, class tag, class Arg1, class Arg2, class Arg3>
|
||||
inline detail::big_number_exp<detail::minus, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >
|
||||
operator - (const big_number<B>& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::minus, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class B>
|
||||
inline detail::big_number_exp<detail::minus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >
|
||||
operator - (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::minus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
|
||||
inline detail::big_number_exp<detail::minus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >
|
||||
operator - (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::minus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class V>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::minus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V > >::type
|
||||
operator - (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::minus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
|
||||
}
|
||||
template <class V, class tag, class Arg1, class Arg2, class Arg3>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::minus, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> > >::type
|
||||
operator - (const V& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::minus, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
|
||||
}
|
||||
//
|
||||
// Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
|
||||
//
|
||||
template <class B, class Arg1, class Arg2, class Arg3>
|
||||
inline detail::big_number_exp<detail::plus, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >
|
||||
operator - (const big_number<B>& a, const detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::plus, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(a, b.left_ref());
|
||||
}
|
||||
template <class Arg1, class Arg2, class Arg3, class B>
|
||||
inline detail::big_number_exp<detail::negate, detail::big_number_exp<detail::plus, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > >
|
||||
operator - (const detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::plus, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(b, a.left_ref());
|
||||
}
|
||||
template <class B>
|
||||
inline detail::big_number_exp<detail::add_immediates, big_number<B>, big_number<B> >
|
||||
operator - (const big_number<B>& a, const detail::big_number_exp<detail::negate, big_number<B> >& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::add_immediates, big_number<B>, big_number<B> >(a, b.left_ref());
|
||||
}
|
||||
template <class B>
|
||||
inline detail::big_number_exp<detail::negate, detail::big_number_exp<detail::add_immediates, big_number<B>, big_number<B> > >
|
||||
operator - (const detail::big_number_exp<detail::negate, big_number<B> >& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::add_immediates, big_number<B>, big_number<B> >(b, a.left_ref());
|
||||
}
|
||||
template <class B, class V>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::negate, detail::big_number_exp<detail::add_immediates, big_number<B>, V > > >::type
|
||||
operator - (const detail::big_number_exp<detail::negate, big_number<B> >& a, const V& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::add_immediates, V, big_number<B> >(b, a.left_ref());
|
||||
}
|
||||
template <class V, class B>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::add_immediates, V, big_number<B> > >::type
|
||||
operator - (const V& a, const detail::big_number_exp<detail::negate, big_number<B> >& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::add_immediates, V, big_number<B> >(a, b.left_ref());
|
||||
}
|
||||
//
|
||||
// Multiplication:
|
||||
//
|
||||
template <class B>
|
||||
inline detail::big_number_exp<detail::multiply_immediates, big_number<B>, big_number<B> >
|
||||
operator * (const big_number<B>& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::multiply_immediates, big_number<B>, big_number<B> >(a, b);
|
||||
}
|
||||
template <class B, class V>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::multiply_immediates, big_number<B>, V > >::type
|
||||
operator * (const big_number<B>& a, const V& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::multiply_immediates, big_number<B>, V >(a, b);
|
||||
}
|
||||
template <class V, class B>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::multiply_immediates, V, big_number<B> > >::type
|
||||
operator * (const V& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::multiply_immediates, V, big_number<B> >(a, b);
|
||||
}
|
||||
template <class B, class tag, class Arg1, class Arg2, class Arg3>
|
||||
inline detail::big_number_exp<detail::multiplies, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >
|
||||
operator * (const big_number<B>& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::multiplies, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class B>
|
||||
inline detail::big_number_exp<detail::multiplies, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >
|
||||
operator * (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::multiplies, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
|
||||
inline detail::big_number_exp<detail::multiplies, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >
|
||||
operator * (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::multiplies, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class V>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::multiplies, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V > >::type
|
||||
operator * (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::multiplies, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
|
||||
}
|
||||
template <class V, class tag, class Arg1, class Arg2, class Arg3>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::multiplies, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> > >::type
|
||||
operator * (const V& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::multiplies, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
|
||||
}
|
||||
//
|
||||
// Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
|
||||
//
|
||||
template <class B, class Arg1, class Arg2, class Arg3>
|
||||
inline detail::big_number_exp<detail::negate, detail::big_number_exp<detail::multiplies, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > >
|
||||
operator * (const big_number<B>& a, const detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::multiplies, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > (a, b.left_ref());
|
||||
}
|
||||
template <class Arg1, class Arg2, class Arg3, class B>
|
||||
inline detail::big_number_exp<detail::negate, detail::big_number_exp<detail::multiplies, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > >
|
||||
operator * (const detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::multiplies, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(b, a.left_ref());
|
||||
}
|
||||
template <class B>
|
||||
inline detail::big_number_exp<detail::negate, detail::big_number_exp<detail::multiply_immediates, big_number<B>, big_number<B> > >
|
||||
operator * (const big_number<B>& a, const detail::big_number_exp<detail::negate, big_number<B> >& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::multiply_immediates, big_number<B>, big_number<B> >(a, b.left_ref());
|
||||
}
|
||||
template <class B>
|
||||
inline detail::big_number_exp<detail::negate, detail::big_number_exp<detail::multiply_immediates, big_number<B>, big_number<B> > >
|
||||
operator * (const detail::big_number_exp<detail::negate, big_number<B> >& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::multiply_immediates, big_number<B>, big_number<B> >(b, a.left_ref());
|
||||
}
|
||||
template <class B, class V>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::negate, detail::big_number_exp<detail::multiply_immediates, big_number<B>, V > > >::type
|
||||
operator * (const detail::big_number_exp<detail::negate, big_number<B> >& a, const V& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::multiply_immediates, big_number<B>, V >(a.left_ref(), b);
|
||||
}
|
||||
template <class V, class B>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::negate, detail::big_number_exp<detail::multiply_immediates, big_number<B>, V > > >::type
|
||||
operator * (const V& a, const detail::big_number_exp<detail::negate, big_number<B> >& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::multiply_immediates, big_number<B>, V >(b.left_ref(), a);
|
||||
}
|
||||
//
|
||||
// Division:
|
||||
//
|
||||
template <class B>
|
||||
inline detail::big_number_exp<detail::divide_immediates, big_number<B>, big_number<B> >
|
||||
operator / (const big_number<B>& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::divide_immediates, big_number<B>, big_number<B> >(a, b);
|
||||
}
|
||||
template <class B, class V>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::divide_immediates, big_number<B>, V > >::type
|
||||
operator / (const big_number<B>& a, const V& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::divide_immediates, big_number<B>, V >(a, b);
|
||||
}
|
||||
template <class V, class B>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::divide_immediates, V, big_number<B> > >::type
|
||||
operator / (const V& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::divide_immediates, V, big_number<B> >(a, b);
|
||||
}
|
||||
template <class B, class tag, class Arg1, class Arg2, class Arg3>
|
||||
inline detail::big_number_exp<detail::divides, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >
|
||||
operator / (const big_number<B>& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::divides, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class B>
|
||||
inline detail::big_number_exp<detail::divides, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >
|
||||
operator / (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::divides, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
|
||||
inline detail::big_number_exp<detail::divides, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >
|
||||
operator / (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::divides, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class V>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::divides, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V > >::type
|
||||
operator / (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::divides, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
|
||||
}
|
||||
template <class V, class tag, class Arg1, class Arg2, class Arg3>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::divides, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> > >::type
|
||||
operator / (const V& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::divides, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
|
||||
}
|
||||
//
|
||||
// Repeat operator for negated arguments: propagate the negation to the top level to avoid temporaries:
|
||||
//
|
||||
template <class B, class Arg1, class Arg2, class Arg3>
|
||||
inline detail::big_number_exp<detail::negate, detail::big_number_exp<detail::divides, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type > >
|
||||
operator / (const big_number<B>& a, const detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::divides, big_number<B>, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type >(a, b.left_ref());
|
||||
}
|
||||
template <class Arg1, class Arg2, class Arg3, class B>
|
||||
inline detail::big_number_exp<detail::negate, detail::big_number_exp<detail::divides, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type, big_number<B> > >
|
||||
operator / (const detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::divides, typename detail::big_number_exp<detail::negate, Arg1, Arg2, Arg3>::left_type, big_number<B> >(a.left_ref(), b);
|
||||
}
|
||||
template <class B>
|
||||
inline detail::big_number_exp<detail::negate, detail::big_number_exp<detail::divide_immediates, big_number<B>, big_number<B> > >
|
||||
operator / (const big_number<B>& a, const detail::big_number_exp<detail::negate, big_number<B> >& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::divide_immediates, big_number<B>, big_number<B> >(a, b.left_ref());
|
||||
}
|
||||
template <class B>
|
||||
inline detail::big_number_exp<detail::negate, detail::big_number_exp<detail::divide_immediates, big_number<B>, big_number<B> > >
|
||||
operator / (const detail::big_number_exp<detail::negate, big_number<B> >& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::divide_immediates, big_number<B>, big_number<B> >(a.left_ref(), b);
|
||||
}
|
||||
template <class B, class V>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::negate, detail::big_number_exp<detail::divide_immediates, big_number<B>, V > > >::type
|
||||
operator / (const detail::big_number_exp<detail::negate, big_number<B> >& a, const V& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::divide_immediates, big_number<B>, V>(a.left_ref(), b);
|
||||
}
|
||||
template <class V, class B>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::negate, detail::big_number_exp<detail::divide_immediates, V, big_number<B> > > >::type
|
||||
operator / (const V& a, const detail::big_number_exp<detail::negate, big_number<B> >& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::divide_immediates, V, big_number<B> >(a, b.left_ref());
|
||||
}
|
||||
//
|
||||
// Modulus:
|
||||
//
|
||||
template <class B>
|
||||
inline detail::big_number_exp<detail::modulus_immediates, big_number<B>, big_number<B> >
|
||||
operator % (const big_number<B>& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::modulus_immediates, big_number<B>, big_number<B> >(a, b);
|
||||
}
|
||||
template <class B, class V>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::modulus_immediates, big_number<B>, V > >::type
|
||||
operator % (const big_number<B>& a, const V& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::modulus_immediates, big_number<B>, V >(a, b);
|
||||
}
|
||||
template <class V, class B>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::modulus_immediates, V, big_number<B> > >::type
|
||||
operator % (const V& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::modulus_immediates, V, big_number<B> >(a, b);
|
||||
}
|
||||
template <class B, class tag, class Arg1, class Arg2, class Arg3>
|
||||
inline detail::big_number_exp<detail::modulus, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >
|
||||
operator % (const big_number<B>& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::modulus, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class B>
|
||||
inline detail::big_number_exp<detail::modulus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >
|
||||
operator % (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::modulus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
|
||||
inline detail::big_number_exp<detail::modulus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >
|
||||
operator % (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::modulus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class V>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::modulus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V > >::type
|
||||
operator % (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::modulus, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
|
||||
}
|
||||
template <class V, class tag, class Arg1, class Arg2, class Arg3>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::modulus, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> > >::type
|
||||
operator % (const V& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::modulus, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
|
||||
}
|
||||
//
|
||||
// Left shift:
|
||||
//
|
||||
template <class B, class I>
|
||||
inline typename enable_if<is_integral<I>, detail::big_number_exp<detail::shift_left, big_number<B>, I > >::type
|
||||
operator << (const big_number<B>& a, const I& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::shift_left, big_number<B>, I>(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class I>
|
||||
inline typename enable_if<is_integral<I>, detail::big_number_exp<detail::shift_left, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, I> >::type
|
||||
operator << (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const I& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::shift_left, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, I>(a, b);
|
||||
}
|
||||
//
|
||||
// Right shift:
|
||||
//
|
||||
template <class B, class I>
|
||||
inline typename enable_if<is_integral<I>, detail::big_number_exp<detail::shift_right, big_number<B>, I > >::type
|
||||
operator >> (const big_number<B>& a, const I& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::shift_right, big_number<B>, I>(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class I>
|
||||
inline typename enable_if<is_integral<I>, detail::big_number_exp<detail::shift_right, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, I> >::type
|
||||
operator >> (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const I& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::shift_right, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, I>(a, b);
|
||||
}
|
||||
//
|
||||
// Bitwise AND:
|
||||
//
|
||||
template <class B>
|
||||
inline detail::big_number_exp<detail::bitwise_and_immediates, big_number<B>, big_number<B> >
|
||||
operator & (const big_number<B>& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_and_immediates, big_number<B>, big_number<B> >(a, b);
|
||||
}
|
||||
template <class B, class V>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_and_immediates, big_number<B>, V > >::type
|
||||
operator & (const big_number<B>& a, const V& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_and_immediates, big_number<B>, V >(a, b);
|
||||
}
|
||||
template <class V, class B>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_and_immediates, V, big_number<B> > >::type
|
||||
operator & (const V& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_and_immediates, V, big_number<B> >(a, b);
|
||||
}
|
||||
template <class B, class tag, class Arg1, class Arg2, class Arg3>
|
||||
inline detail::big_number_exp<detail::bitwise_and, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >
|
||||
operator & (const big_number<B>& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_and, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class B>
|
||||
inline detail::big_number_exp<detail::bitwise_and, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >
|
||||
operator & (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_and, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
|
||||
inline detail::big_number_exp<detail::bitwise_and, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >
|
||||
operator & (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_and, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class V>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_and, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V > >::type
|
||||
operator & (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_and, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
|
||||
}
|
||||
template <class V, class tag, class Arg1, class Arg2, class Arg3>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_and, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> > >::type
|
||||
operator & (const V& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_and, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
|
||||
}
|
||||
//
|
||||
// Bitwise OR:
|
||||
//
|
||||
template <class B>
|
||||
inline detail::big_number_exp<detail::bitwise_or_immediates, big_number<B>, big_number<B> >
|
||||
operator| (const big_number<B>& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_or_immediates, big_number<B>, big_number<B> >(a, b);
|
||||
}
|
||||
template <class B, class V>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_or_immediates, big_number<B>, V > >::type
|
||||
operator| (const big_number<B>& a, const V& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_or_immediates, big_number<B>, V >(a, b);
|
||||
}
|
||||
template <class V, class B>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_or_immediates, V, big_number<B> > >::type
|
||||
operator| (const V& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_or_immediates, V, big_number<B> >(a, b);
|
||||
}
|
||||
template <class B, class tag, class Arg1, class Arg2, class Arg3>
|
||||
inline detail::big_number_exp<detail::bitwise_or, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >
|
||||
operator| (const big_number<B>& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_or, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class B>
|
||||
inline detail::big_number_exp<detail::bitwise_or, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >
|
||||
operator| (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_or, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
|
||||
inline detail::big_number_exp<detail::bitwise_or, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >
|
||||
operator| (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_or, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class V>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_or, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V > >::type
|
||||
operator| (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_or, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
|
||||
}
|
||||
template <class V, class tag, class Arg1, class Arg2, class Arg3>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_or, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> > >::type
|
||||
operator| (const V& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_or, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
|
||||
}
|
||||
//
|
||||
// Bitwise XOR:
|
||||
//
|
||||
template <class B>
|
||||
inline detail::big_number_exp<detail::bitwise_xor_immediates, big_number<B>, big_number<B> >
|
||||
operator^ (const big_number<B>& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_xor_immediates, big_number<B>, big_number<B> >(a, b);
|
||||
}
|
||||
template <class B, class V>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_xor_immediates, big_number<B>, V > >::type
|
||||
operator^ (const big_number<B>& a, const V& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_xor_immediates, big_number<B>, V >(a, b);
|
||||
}
|
||||
template <class V, class B>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_xor_immediates, V, big_number<B> > >::type
|
||||
operator^ (const V& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_xor_immediates, V, big_number<B> >(a, b);
|
||||
}
|
||||
template <class B, class tag, class Arg1, class Arg2, class Arg3>
|
||||
inline detail::big_number_exp<detail::bitwise_xor, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >
|
||||
operator^ (const big_number<B>& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_xor, big_number<B>, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class B>
|
||||
inline detail::big_number_exp<detail::bitwise_xor, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >
|
||||
operator^ (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const big_number<B>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_xor, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, big_number<B> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class tag2, class Arg1b, class Arg2b, class Arg3b>
|
||||
inline detail::big_number_exp<detail::bitwise_xor, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >
|
||||
operator^ (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_xor, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, detail::big_number_exp<tag2, Arg1b, Arg2b, Arg3b> >(a, b);
|
||||
}
|
||||
template <class tag, class Arg1, class Arg2, class Arg3, class V>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_xor, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V > >::type
|
||||
operator^ (const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& a, const V& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_xor, detail::big_number_exp<tag, Arg1, Arg2, Arg3>, V >(a, b);
|
||||
}
|
||||
template <class V, class tag, class Arg1, class Arg2, class Arg3>
|
||||
inline typename enable_if<is_arithmetic<V>, detail::big_number_exp<detail::bitwise_xor, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> > >::type
|
||||
operator^ (const V& a, const detail::big_number_exp<tag, Arg1, Arg2, Arg3>& b)
|
||||
{
|
||||
return detail::big_number_exp<detail::bitwise_xor, V, detail::big_number_exp<tag, Arg1, Arg2, Arg3> >(a, b);
|
||||
}
|
||||
|
||||
//
|
||||
// Traits class, lets us know what kind of number we have, defaults to a floating point type:
|
||||
//
|
||||
enum number_category_type
|
||||
{
|
||||
number_kind_integer = 0,
|
||||
number_kind_floating_point = 1,
|
||||
number_kind_rational = 2,
|
||||
number_kind_fixed_point = 3
|
||||
};
|
||||
|
||||
template <class Num>
|
||||
struct number_category : public mpl::int_<number_kind_floating_point> {};
|
||||
template <class Backend>
|
||||
struct number_category<big_number<Backend> > : public number_category<Backend>{};
|
||||
template <class tag, class A1, class A2, class A3>
|
||||
struct number_category<detail::big_number_exp<tag, A1, A2, A3> > : public number_category<typename detail::big_number_exp<tag, A1, A2, A3>::result_type>{};
|
||||
|
||||
}} // namespaces
|
||||
|
||||
namespace boost{ namespace math{ namespace tools{
|
||||
|
||||
template <class T>
|
||||
struct promote_arg;
|
||||
|
||||
template <class tag, class A1, class A2, class A3>
|
||||
struct promote_arg<boost::math::detail::big_number_exp<tag, A1, A2, A3> >
|
||||
{
|
||||
typedef typename boost::math::detail::big_number_exp<tag, A1, A2, A3>::result_type type;
|
||||
};
|
||||
|
||||
}}}
|
||||
|
||||
#endif // BOOST_MATH_BIG_NUM_BASE_HPP
|
||||
|
||||
|
||||
@@ -1,903 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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_BIG_NUM_DEF_OPS
|
||||
#define BOOST_MATH_BIG_NUM_DEF_OPS
|
||||
|
||||
#include <boost/math/policies/error_handling.hpp>
|
||||
#include <boost/math/big_number/big_number_base.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/mpl/front.hpp>
|
||||
|
||||
namespace boost{ namespace math{ namespace big_num_default_ops{
|
||||
|
||||
//
|
||||
// Default versions of mixed arithmetic, these just construct a temporary
|
||||
// from the arithmetic value and then do the arithmetic on that:
|
||||
//
|
||||
template <class T, class V>
|
||||
inline typename enable_if<mpl::or_<is_arithmetic<V>, is_convertible<V, const char*>, is_same<V, std::string> > >::type
|
||||
add(T& result, V const& v)
|
||||
{
|
||||
T t;
|
||||
t = v;
|
||||
add(result, t);
|
||||
}
|
||||
template <class T, class V>
|
||||
inline typename enable_if<mpl::or_<is_arithmetic<V>, is_convertible<V, const char*>, is_same<V, std::string> > >::type
|
||||
subtract(T& result, V const& v)
|
||||
{
|
||||
T t;
|
||||
t = v;
|
||||
subtract(result, t);
|
||||
}
|
||||
template <class T, class V>
|
||||
inline typename enable_if<mpl::or_<is_arithmetic<V>, is_convertible<V, const char*>, is_same<V, std::string> > >::type
|
||||
multiply(T& result, V const& v)
|
||||
{
|
||||
T t;
|
||||
t = v;
|
||||
multiply(result, t);
|
||||
}
|
||||
template <class T, class V>
|
||||
inline typename enable_if<mpl::or_<is_arithmetic<V>, is_convertible<V, const char*>, is_same<V, std::string> > >::type
|
||||
divide(T& result, V const& v)
|
||||
{
|
||||
T t;
|
||||
t = v;
|
||||
divide(result, t);
|
||||
}
|
||||
template <class T, class V>
|
||||
inline typename enable_if<mpl::or_<is_arithmetic<V>, is_convertible<V, const char*>, is_same<V, std::string> > >::type
|
||||
modulus(T& result, V const& v)
|
||||
{
|
||||
T t;
|
||||
t = v;
|
||||
modulus(result, t);
|
||||
}
|
||||
template <class T, class V>
|
||||
inline typename enable_if<mpl::or_<is_arithmetic<V>, is_convertible<V, const char*>, is_same<V, std::string> > >::type
|
||||
bitwise_and(T& result, V const& v)
|
||||
{
|
||||
T t;
|
||||
t = v;
|
||||
bitwise_and(result, t);
|
||||
}
|
||||
template <class T, class V>
|
||||
inline typename enable_if<mpl::or_<is_arithmetic<V>, is_convertible<V, const char*>, is_same<V, std::string> > >::type
|
||||
bitwise_or(T& result, V const& v)
|
||||
{
|
||||
T t;
|
||||
t = v;
|
||||
bitwise_or(result, t);
|
||||
}
|
||||
template <class T, class V>
|
||||
inline typename enable_if<mpl::or_<is_arithmetic<V>, is_convertible<V, const char*>, is_same<V, std::string> > >::type
|
||||
bitwise_xor(T& result, V const& v)
|
||||
{
|
||||
T t;
|
||||
t = v;
|
||||
bitwise_xor(result, t);
|
||||
}
|
||||
|
||||
template <class T, class V>
|
||||
inline typename enable_if<mpl::or_<is_arithmetic<V>, is_convertible<V, const char*>, is_same<V, std::string> > >::type
|
||||
complement(T& result, V const& v)
|
||||
{
|
||||
T t;
|
||||
t = v;
|
||||
complement(result, t);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool is_same_object(const T& u, const T&v)
|
||||
{ return &u == &v; }
|
||||
template <class T, class U>
|
||||
inline bool is_same_object(const T& u, const U&v)
|
||||
{ return false; }
|
||||
|
||||
//
|
||||
// Default versions of 3-arg arithmetic functions, these just forward to the 2 arg versions:
|
||||
//
|
||||
template <class T, class U, class V>
|
||||
inline void add(T& t, const U& u, const V& v)
|
||||
{
|
||||
if(is_same_object(t, v))
|
||||
{
|
||||
add(t, u);
|
||||
}
|
||||
else if(is_same_object(t, u))
|
||||
{
|
||||
add(t, v);
|
||||
}
|
||||
else
|
||||
{
|
||||
t = u;
|
||||
add(t, v);
|
||||
}
|
||||
}
|
||||
template <class T, class U, class V>
|
||||
inline void subtract(T& t, const U& u, const V& v)
|
||||
{
|
||||
if(is_same_object(t, u))
|
||||
subtract(t, v);
|
||||
else if(is_same_object(t, v))
|
||||
{
|
||||
subtract(t, u);
|
||||
t.negate();
|
||||
}
|
||||
else
|
||||
{
|
||||
t = u;
|
||||
subtract(t, v);
|
||||
}
|
||||
}
|
||||
template <class T, class U, class V>
|
||||
inline void multiply(T& t, const U& u, const V& v)
|
||||
{
|
||||
if(is_same_object(t, u))
|
||||
multiply(t, v);
|
||||
else if(is_same_object(t, v))
|
||||
multiply(t, u);
|
||||
else
|
||||
{
|
||||
t = u;
|
||||
multiply(t, v);
|
||||
}
|
||||
}
|
||||
template <class T, class U, class V>
|
||||
inline void divide(T& t, const U& u, const V& v)
|
||||
{
|
||||
if(is_same_object(t, u))
|
||||
divide(t, v);
|
||||
else if(is_same_object(t, v))
|
||||
{
|
||||
T temp = t;
|
||||
divide(temp, u, v);
|
||||
temp.swap(t);
|
||||
}
|
||||
else
|
||||
{
|
||||
t = u;
|
||||
divide(t, v);
|
||||
}
|
||||
}
|
||||
template <class T, class U, class V>
|
||||
inline void modulus(T& t, const U& u, const V& v)
|
||||
{
|
||||
if(is_same_object(t, u))
|
||||
modulus(t, v);
|
||||
else if(is_same_object(t, v))
|
||||
{
|
||||
T temp;
|
||||
modulus(temp, u, v);
|
||||
temp.swap(t);
|
||||
}
|
||||
else
|
||||
{
|
||||
t = u;
|
||||
modulus(t, v);
|
||||
}
|
||||
}
|
||||
template <class T, class U, class V>
|
||||
inline void bitwise_and(T& t, const U& u, const V& v)
|
||||
{
|
||||
if(is_same_object(t, u))
|
||||
bitwise_and(t, v);
|
||||
else if(is_same_object(t, v))
|
||||
bitwise_and(t, u);
|
||||
else
|
||||
{
|
||||
t = u;
|
||||
bitwise_and(t, v);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class U, class V>
|
||||
inline void bitwise_or(T& t, const U& u, const V& v)
|
||||
{
|
||||
if(is_same_object(t, u))
|
||||
bitwise_or(t, v);
|
||||
else if(is_same_object(t, v))
|
||||
bitwise_or(t, u);
|
||||
else
|
||||
{
|
||||
t = u;
|
||||
bitwise_or(t, v);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T, class U, class V>
|
||||
inline void bitwise_xor(T& t, const U& u, const V& v)
|
||||
{
|
||||
if(is_same_object(t, u))
|
||||
bitwise_xor(t, v);
|
||||
else if(is_same_object(t, v))
|
||||
bitwise_xor(t, u);
|
||||
else
|
||||
{
|
||||
t = u;
|
||||
bitwise_xor(t, v);
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void increment(T& val)
|
||||
{
|
||||
typedef typename mpl::front<typename T::unsigned_types>::type ui_type;
|
||||
add(val, static_cast<ui_type>(1u));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void decrement(T& val)
|
||||
{
|
||||
typedef typename mpl::front<typename T::unsigned_types>::type ui_type;
|
||||
subtract(val, static_cast<ui_type>(1u));
|
||||
}
|
||||
|
||||
template <class T, class V>
|
||||
inline void left_shift(T& result, const T& arg, const V val)
|
||||
{
|
||||
result = arg;
|
||||
left_shift(result, val);
|
||||
}
|
||||
|
||||
template <class T, class V>
|
||||
inline void right_shift(T& result, const T& arg, const V val)
|
||||
{
|
||||
result = arg;
|
||||
right_shift(result, val);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline bool is_zero(const T& val)
|
||||
{
|
||||
typedef typename mpl::front<typename T::unsigned_types>::type ui_type;
|
||||
return val.compare(static_cast<ui_type>(0)) == 0;
|
||||
}
|
||||
template <class T>
|
||||
inline int get_sign(const T& val)
|
||||
{
|
||||
typedef typename mpl::front<typename T::unsigned_types>::type ui_type;
|
||||
return val.compare(static_cast<ui_type>(0));
|
||||
}
|
||||
|
||||
template <class R, int b>
|
||||
struct has_enough_bits
|
||||
{
|
||||
template <class T>
|
||||
struct type : public mpl::and_<mpl::not_<is_same<R, T> >, mpl::bool_<std::numeric_limits<T>::digits >= b> >{};
|
||||
};
|
||||
|
||||
template <class R>
|
||||
struct terminal
|
||||
{
|
||||
terminal(const R& v) : value(v){}
|
||||
terminal(){}
|
||||
terminal& operator = (R val) { value = val; }
|
||||
R value;
|
||||
operator R()const { return value; }
|
||||
};
|
||||
|
||||
template<class R, class B>
|
||||
struct calculate_next_larger_type
|
||||
{
|
||||
typedef typename mpl::if_<
|
||||
is_signed<R>,
|
||||
typename B::signed_types,
|
||||
typename mpl::if_<
|
||||
is_unsigned<R>,
|
||||
typename B::unsigned_types,
|
||||
typename B::real_types
|
||||
>::type
|
||||
>::type list_type;
|
||||
typedef typename has_enough_bits<R, std::numeric_limits<R>::digits>::template type<mpl::_> pred_type;
|
||||
typedef typename mpl::find_if<
|
||||
list_type,
|
||||
pred_type
|
||||
>::type iter_type;
|
||||
typedef typename mpl::eval_if<
|
||||
is_same<typename mpl::end<list_type>::type, iter_type>,
|
||||
mpl::identity<terminal<R> >,
|
||||
mpl::deref<iter_type>
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <class R, class B>
|
||||
inline void convert_to(R* result, const B& backend)
|
||||
{
|
||||
typedef typename calculate_next_larger_type<R, B>::type next_type;
|
||||
next_type n;
|
||||
convert_to(&n, backend);
|
||||
*result = static_cast<R>(n);
|
||||
}
|
||||
|
||||
template <class R, class B>
|
||||
inline void convert_to(terminal<R>* result, const B& backend)
|
||||
{
|
||||
//
|
||||
// We ran out of types to try for the convertion, try
|
||||
// a lexical_cast and hope for the best:
|
||||
//
|
||||
result->value = boost::lexical_cast<R>(backend.str(0, false));
|
||||
}
|
||||
|
||||
//
|
||||
// Functions:
|
||||
//
|
||||
template <class T>
|
||||
void eval_abs(T& result, const T& arg)
|
||||
{
|
||||
typedef typename T::signed_types type_list;
|
||||
typedef typename mpl::front<type_list>::type front;
|
||||
*result = arg;
|
||||
if(arg.compare(front(0)) < 0)
|
||||
result->negate();
|
||||
}
|
||||
template <class T>
|
||||
void eval_fabs(T& result, const T& arg)
|
||||
{
|
||||
typedef typename T::signed_types type_list;
|
||||
typedef typename mpl::front<type_list>::type front;
|
||||
*result = arg;
|
||||
if(arg.compare(front(0)) < 0)
|
||||
result->negate();
|
||||
}
|
||||
|
||||
template <class Backend>
|
||||
inline int eval_fpclassify(const Backend& arg)
|
||||
{
|
||||
return is_zero(arg) ? FP_ZERO : FP_NORMAL;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
inline void eval_fmod(T& result, const T& a, const T& b)
|
||||
{
|
||||
if((&result == &a) || (&result == &b))
|
||||
{
|
||||
T temp;
|
||||
eval_fmod(temp, a, b);
|
||||
result = temp;
|
||||
}
|
||||
T n;
|
||||
divide(result, a, b);
|
||||
if(get_sign(a) < 0)
|
||||
eval_ceil(n, result);
|
||||
else
|
||||
eval_floor(n, result);
|
||||
multiply(n, b);
|
||||
subtract(result, a, n);
|
||||
}
|
||||
|
||||
//
|
||||
// These have to implemented by the backend, declared here so that our macro generated code compiles OK.
|
||||
//
|
||||
template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::type eval_floor();
|
||||
template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::type eval_ceil();
|
||||
template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::type eval_trunc();
|
||||
template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::type eval_sqrt();
|
||||
template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::type eval_ldexp();
|
||||
template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::type eval_frexp();
|
||||
//
|
||||
// TODO: implement default versions of these:
|
||||
//
|
||||
template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::type eval_exp();
|
||||
template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::type eval_log();
|
||||
template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::type eval_sin();
|
||||
template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::type eval_cos();
|
||||
template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::type eval_tan();
|
||||
template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::type eval_asin();
|
||||
template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::type eval_acos();
|
||||
template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::type eval_atan();
|
||||
template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::type eval_sinh();
|
||||
template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::type eval_cosh();
|
||||
template <class T>
|
||||
typename enable_if_c<sizeof(T) == 0>::type eval_tanh();
|
||||
//
|
||||
// These functions are implemented in separate files, but expanded inline here:
|
||||
//
|
||||
#include <boost/math/big_number/functions/pow.hpp>
|
||||
|
||||
}
|
||||
|
||||
template <class Backend>
|
||||
class big_number;
|
||||
|
||||
//
|
||||
// Default versions of floating point classification routines:
|
||||
//
|
||||
template <class Backend>
|
||||
inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(const big_number<Backend>& arg)
|
||||
{
|
||||
using big_num_default_ops::eval_fpclassify;
|
||||
return eval_fpclassify(arg.backend());
|
||||
}
|
||||
template <class tag, class A1, class A2, class A3>
|
||||
inline int fpclassify BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<tag, A1, A2, A3>& arg)
|
||||
{
|
||||
typedef typename detail::big_number_exp<tag, A1, A2, A3>::result_type value_type;
|
||||
return fpclassify(value_type(arg));
|
||||
}
|
||||
template <class Backend>
|
||||
inline bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(const big_number<Backend>& arg)
|
||||
{
|
||||
int v = fpclassify(arg);
|
||||
return (v != FP_INFINITE) && (v != FP_NAN);
|
||||
}
|
||||
template <class tag, class A1, class A2, class A3>
|
||||
inline bool isfinite BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<tag, A1, A2, A3>& arg)
|
||||
{
|
||||
typedef typename detail::big_number_exp<tag, A1, A2, A3>::result_type value_type;
|
||||
return isfinite(value_type(arg));
|
||||
}
|
||||
template <class Backend>
|
||||
inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(const big_number<Backend>& arg)
|
||||
{
|
||||
return fpclassify(arg) == FP_NAN;
|
||||
}
|
||||
template <class tag, class A1, class A2, class A3>
|
||||
inline bool isnan BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<tag, A1, A2, A3>& arg)
|
||||
{
|
||||
typedef typename detail::big_number_exp<tag, A1, A2, A3>::result_type value_type;
|
||||
return isnan(value_type(arg));
|
||||
}
|
||||
template <class Backend>
|
||||
inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(const big_number<Backend>& arg)
|
||||
{
|
||||
return fpclassify(arg) == FP_INFINITE;
|
||||
}
|
||||
template <class tag, class A1, class A2, class A3>
|
||||
inline bool isinf BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<tag, A1, A2, A3>& arg)
|
||||
{
|
||||
typedef typename detail::big_number_exp<tag, A1, A2, A3>::result_type value_type;
|
||||
return isinf(value_type(arg));
|
||||
}
|
||||
template <class Backend>
|
||||
inline bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(const big_number<Backend>& arg)
|
||||
{
|
||||
return fpclassify(arg) == FP_NORMAL;
|
||||
}
|
||||
template <class tag, class A1, class A2, class A3>
|
||||
inline bool isnormal BOOST_PREVENT_MACRO_SUBSTITUTION(const detail::big_number_exp<tag, A1, A2, A3>& arg)
|
||||
{
|
||||
typedef typename detail::big_number_exp<tag, A1, A2, A3>::result_type value_type;
|
||||
return isnormal(value_type(arg));
|
||||
}
|
||||
|
||||
template <class tag, class A1, class A2, class A3, class Policy>
|
||||
inline int itrunc(const detail::big_number_exp<tag, A1, A2, A3>& v, const Policy& pol)
|
||||
{
|
||||
typedef typename detail::big_number_exp<tag, A1, A2, A3>::result_type number_type;
|
||||
number_type r = trunc(v, pol);
|
||||
if(fabs(r) > (std::numeric_limits<int>::max)())
|
||||
return policies::raise_rounding_error("boost::math::itrunc<%1%>(%1%)", 0, v, 0, pol).template convert_to<int>();
|
||||
return r.template convert_to<int>();
|
||||
}
|
||||
template <class Backend, class Policy>
|
||||
inline int itrunc(const big_number<Backend>& v, const Policy& pol)
|
||||
{
|
||||
big_number<Backend> r = trunc(v, pol);
|
||||
if(fabs(r) > (std::numeric_limits<int>::max)())
|
||||
return policies::raise_rounding_error("boost::math::itrunc<%1%>(%1%)", 0, v, 0, pol).template convert_to<int>();
|
||||
return r.template convert_to<int>();
|
||||
}
|
||||
template <class tag, class A1, class A2, class A3, class Policy>
|
||||
inline long ltrunc(const detail::big_number_exp<tag, A1, A2, A3>& v, const Policy& pol)
|
||||
{
|
||||
typedef typename detail::big_number_exp<tag, A1, A2, A3>::result_result number_type;
|
||||
number_type r = trunc(v, pol);
|
||||
if(fabs(r) > (std::numeric_limits<long>::max)())
|
||||
return policies::raise_rounding_error("boost::math::ltrunc<%1%>(%1%)", 0, v, 0L, pol).template convert_to<long>();
|
||||
return r.template convert_to<long>();
|
||||
}
|
||||
template <class T, class Policy>
|
||||
inline long ltrunc(const big_number<T>& v, const Policy& pol)
|
||||
{
|
||||
big_number<T> r = trunc(v, pol);
|
||||
if(fabs(r) > (std::numeric_limits<long>::max)())
|
||||
return policies::raise_rounding_error("boost::math::ltrunc<%1%>(%1%)", 0, v, 0L, pol).template convert_to<long>();
|
||||
return r.template convert_to<long>();
|
||||
}
|
||||
#ifndef BOOST_NO_LONG_LONG
|
||||
template <class tag, class A1, class A2, class A3, class Policy>
|
||||
inline long long lltrunc(const detail::big_number_exp<tag, A1, A2, A3>& v, const Policy& pol)
|
||||
{
|
||||
typedef typename detail::big_number_exp<tag, A1, A2, A3>::result_result number_type;
|
||||
number_type r = trunc(v, pol);
|
||||
if(fabs(r) > (std::numeric_limits<long long>::max)())
|
||||
return policies::raise_rounding_error("boost::math::lltrunc<%1%>(%1%)", 0, v, 0LL, pol).template convert_to<long long>();
|
||||
return r.template convert_to<long long>();
|
||||
}
|
||||
template <class T, class Policy>
|
||||
inline long long lltrunc(const big_number<T>& v, const Policy& pol)
|
||||
{
|
||||
big_number<T> r = trunc(v, pol);
|
||||
if(fabs(r) > (std::numeric_limits<long long>::max)())
|
||||
return policies::raise_rounding_error("boost::math::lltrunc<%1%>(%1%)", 0, v, 0LL, pol).template convert_to<long long>();
|
||||
return r.template convert_to<long long>();
|
||||
}
|
||||
#endif
|
||||
template <class tag, class A1, class A2, class A3, class Policy>
|
||||
inline int iround(const detail::big_number_exp<tag, A1, A2, A3>& v, const Policy& pol)
|
||||
{
|
||||
typedef typename detail::big_number_exp<tag, A1, A2, A3>::result_result number_type;
|
||||
number_type r = round(v, pol);
|
||||
if(fabs(r) > (std::numeric_limits<int>::max)())
|
||||
return policies::raise_rounding_error("boost::math::iround<%1%>(%1%)", 0, v, 0, pol).template convert_to<int>();
|
||||
return r.template convert_to<int>();
|
||||
}
|
||||
template <class T, class Policy>
|
||||
inline int iround(const big_number<T>& v, const Policy& pol)
|
||||
{
|
||||
big_number<T> r = round(v, pol);
|
||||
if(fabs(r) > (std::numeric_limits<int>::max)())
|
||||
return policies::raise_rounding_error("boost::math::iround<%1%>(%1%)", 0, v, 0, pol).template convert_to<int>();
|
||||
return r.template convert_to<int>();
|
||||
}
|
||||
template <class tag, class A1, class A2, class A3, class Policy>
|
||||
inline long lround(const detail::big_number_exp<tag, A1, A2, A3>& v, const Policy& pol)
|
||||
{
|
||||
typedef typename detail::big_number_exp<tag, A1, A2, A3>::result_result number_type;
|
||||
number_type r = round(v, pol);
|
||||
if(fabs(r) > (std::numeric_limits<long>::max)())
|
||||
return policies::raise_rounding_error("boost::math::lround<%1%>(%1%)", 0, v, 0L, pol).template convert_to<long>();
|
||||
return r.template convert_to<long>();
|
||||
}
|
||||
template <class T, class Policy>
|
||||
inline long lround(const big_number<T>& v, const Policy& pol)
|
||||
{
|
||||
big_number<T> r = round(v, pol);
|
||||
if(fabs(r) > (std::numeric_limits<long>::max)())
|
||||
return policies::raise_rounding_error("boost::math::lround<%1%>(%1%)", 0, v, 0L, pol).template convert_to<long>();
|
||||
return r.template convert_to<long>();
|
||||
}
|
||||
#ifndef BOOST_NO_LONG_LONG
|
||||
template <class tag, class A1, class A2, class A3, class Policy>
|
||||
inline long long llround(const detail::big_number_exp<tag, A1, A2, A3>& v, const Policy& pol)
|
||||
{
|
||||
typedef typename detail::big_number_exp<tag, A1, A2, A3>::result_result number_type;
|
||||
number_type r = round(v, pol);
|
||||
if(fabs(r) > (std::numeric_limits<long long>::max)())
|
||||
return policies::raise_rounding_error("boost::math::iround<%1%>(%1%)", 0, v, 0LL, pol).template convert_to<long long>();
|
||||
return r.template convert_to<long long>();
|
||||
}
|
||||
template <class T, class Policy>
|
||||
inline long long llround(const big_number<T>& v, const Policy& pol)
|
||||
{
|
||||
big_number<T> r = round(v, pol);
|
||||
if(fabs(r) > (std::numeric_limits<long long>::max)())
|
||||
return policies::raise_rounding_error("boost::math::iround<%1%>(%1%)", 0, v, 0LL, pol).template convert_to<long long>();
|
||||
return r.template convert_to<long long>();
|
||||
}
|
||||
#endif
|
||||
//
|
||||
// Overload of Boost.Math functions that find the wrong overload when used with big_number:
|
||||
//
|
||||
namespace detail{
|
||||
template <class T> T sinc_pi_imp(T);
|
||||
template <class T> T sinhc_pi_imp(T);
|
||||
}
|
||||
template <class Backend>
|
||||
inline big_number<Backend> sinc_pi(const big_number<Backend>& x)
|
||||
{
|
||||
return detail::sinc_pi_imp(x);
|
||||
}
|
||||
|
||||
template <class Backend, class Policy>
|
||||
inline big_number<Backend> sinc_pi(const big_number<Backend>& x, const Policy&)
|
||||
{
|
||||
return detail::sinc_pi_imp(x);
|
||||
}
|
||||
|
||||
template <class Backend>
|
||||
inline big_number<Backend> sinhc_pi(const big_number<Backend>& x)
|
||||
{
|
||||
return detail::sinhc_pi_imp(x);
|
||||
}
|
||||
|
||||
template <class Backend, class Policy>
|
||||
inline big_number<Backend> sinhc_pi(const big_number<Backend>& x, const Policy&)
|
||||
{
|
||||
return boost::math::sinhc_pi(x);
|
||||
}
|
||||
|
||||
#define UNARY_OP_FUNCTOR(func)\
|
||||
namespace detail{\
|
||||
template <class Backend> \
|
||||
struct BOOST_JOIN(func, _funct)\
|
||||
{\
|
||||
void operator()(Backend& result, const Backend& arg)const\
|
||||
{\
|
||||
using big_num_default_ops::BOOST_JOIN(eval_,func);\
|
||||
BOOST_JOIN(eval_,func)(result, arg);\
|
||||
}\
|
||||
};\
|
||||
\
|
||||
}\
|
||||
\
|
||||
template <class tag, class A1, class A2, class A3> \
|
||||
detail::big_number_exp<\
|
||||
detail::function\
|
||||
, detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type> \
|
||||
, detail::big_number_exp<tag, A1, A2, A3> \
|
||||
> \
|
||||
func(const detail::big_number_exp<tag, A1, A2, A3>& arg)\
|
||||
{\
|
||||
return detail::big_number_exp<\
|
||||
detail::function\
|
||||
, detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type> \
|
||||
, detail::big_number_exp<tag, A1, A2, A3> \
|
||||
> (\
|
||||
detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type>() \
|
||||
, arg \
|
||||
);\
|
||||
}\
|
||||
template <class Backend> \
|
||||
detail::big_number_exp<\
|
||||
detail::function\
|
||||
, detail::BOOST_JOIN(func, _funct)<Backend> \
|
||||
, big_number<Backend> \
|
||||
> \
|
||||
func(const big_number<Backend>& arg)\
|
||||
{\
|
||||
return detail::big_number_exp<\
|
||||
detail::function\
|
||||
, detail::BOOST_JOIN(func, _funct)<Backend> \
|
||||
, big_number<Backend> \
|
||||
>(\
|
||||
detail::BOOST_JOIN(func, _funct)<Backend>() \
|
||||
, arg \
|
||||
);\
|
||||
}
|
||||
|
||||
#define BINARY_OP_FUNCTOR(func)\
|
||||
namespace detail{\
|
||||
template <class Backend> \
|
||||
struct BOOST_JOIN(func, _funct)\
|
||||
{\
|
||||
void operator()(Backend& result, const Backend& arg, const Backend& a)const\
|
||||
{\
|
||||
using big_num_default_ops:: BOOST_JOIN(eval_,func);\
|
||||
BOOST_JOIN(eval_,func)(result, arg, a);\
|
||||
}\
|
||||
template <class Arithmetic> \
|
||||
void operator()(Backend& result, const Backend& arg, const Arithmetic& a)const\
|
||||
{\
|
||||
using big_num_default_ops:: BOOST_JOIN(eval_,func);\
|
||||
BOOST_JOIN(eval_,func)(result, arg, a);\
|
||||
}\
|
||||
};\
|
||||
\
|
||||
}\
|
||||
template <class Backend> \
|
||||
detail::big_number_exp<\
|
||||
detail::function\
|
||||
, detail::BOOST_JOIN(func, _funct)<Backend> \
|
||||
, big_number<Backend> \
|
||||
, big_number<Backend> \
|
||||
> \
|
||||
func(const big_number<Backend>& arg, const big_number<Backend>& a)\
|
||||
{\
|
||||
return detail::big_number_exp<\
|
||||
detail::function\
|
||||
, detail::BOOST_JOIN(func, _funct)<Backend> \
|
||||
, big_number<Backend> \
|
||||
, big_number<Backend> \
|
||||
>(\
|
||||
detail::BOOST_JOIN(func, _funct)<Backend>() \
|
||||
, arg,\
|
||||
a\
|
||||
);\
|
||||
}\
|
||||
template <class Backend, class tag, class A1, class A2, class A3> \
|
||||
detail::big_number_exp<\
|
||||
detail::function\
|
||||
, detail::BOOST_JOIN(func, _funct)<Backend> \
|
||||
, big_number<Backend> \
|
||||
, detail::big_number_exp<tag, A1, A2, A3> \
|
||||
> \
|
||||
func(const big_number<Backend>& arg, const detail::big_number_exp<tag, A1, A2, A3>& a)\
|
||||
{\
|
||||
return detail::big_number_exp<\
|
||||
detail::function\
|
||||
, detail::BOOST_JOIN(func, _funct)<Backend> \
|
||||
, big_number<Backend> \
|
||||
, detail::big_number_exp<tag, A1, A2, A3> \
|
||||
>(\
|
||||
detail::BOOST_JOIN(func, _funct)<Backend>() \
|
||||
, arg,\
|
||||
a\
|
||||
);\
|
||||
}\
|
||||
template <class tag, class A1, class A2, class A3, class Backend> \
|
||||
detail::big_number_exp<\
|
||||
detail::function\
|
||||
, detail::BOOST_JOIN(func, _funct)<Backend> \
|
||||
, detail::big_number_exp<tag, A1, A2, A3> \
|
||||
, big_number<Backend> \
|
||||
> \
|
||||
func(const detail::big_number_exp<tag, A1, A2, A3>& arg, const big_number<Backend>& a)\
|
||||
{\
|
||||
return detail::big_number_exp<\
|
||||
detail::function\
|
||||
, detail::BOOST_JOIN(func, _funct)<Backend> \
|
||||
, detail::big_number_exp<tag, A1, A2, A3> \
|
||||
, big_number<Backend> \
|
||||
>(\
|
||||
detail::BOOST_JOIN(func, _funct)<Backend>() \
|
||||
, arg,\
|
||||
a\
|
||||
);\
|
||||
}\
|
||||
template <class tag, class A1, class A2, class A3, class tagb, class A1b, class A2b, class A3b> \
|
||||
detail::big_number_exp<\
|
||||
detail::function\
|
||||
, detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type> \
|
||||
, detail::big_number_exp<tag, A1, A2, A3> \
|
||||
, detail::big_number_exp<tagb, A1b, A2b, A3b> \
|
||||
> \
|
||||
func(const detail::big_number_exp<tag, A1, A2, A3>& arg, const detail::big_number_exp<tagb, A1b, A2b, A3b>& a)\
|
||||
{\
|
||||
return detail::big_number_exp<\
|
||||
detail::function\
|
||||
, detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type> \
|
||||
, detail::big_number_exp<tag, A1, A2, A3> \
|
||||
, detail::big_number_exp<tagb, A1b, A2b, A3b> \
|
||||
>(\
|
||||
detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type>() \
|
||||
, arg,\
|
||||
a\
|
||||
);\
|
||||
}\
|
||||
template <class Backend, class Arithmetic> \
|
||||
typename enable_if<\
|
||||
is_arithmetic<Arithmetic>,\
|
||||
detail::big_number_exp<\
|
||||
detail::function\
|
||||
, detail::BOOST_JOIN(func, _funct)<Backend> \
|
||||
, big_number<Backend> \
|
||||
, Arithmetic\
|
||||
> \
|
||||
>::type \
|
||||
func(const big_number<Backend>& arg, const Arithmetic& a)\
|
||||
{\
|
||||
return detail::big_number_exp<\
|
||||
detail::function\
|
||||
, detail::BOOST_JOIN(func, _funct)<Backend> \
|
||||
, big_number<Backend> \
|
||||
, Arithmetic\
|
||||
>(\
|
||||
detail::BOOST_JOIN(func, _funct)<Backend>() \
|
||||
, arg,\
|
||||
a\
|
||||
);\
|
||||
}\
|
||||
template <class tag, class A1, class A2, class A3, class Arithmetic> \
|
||||
typename enable_if<\
|
||||
is_arithmetic<Arithmetic>,\
|
||||
detail::big_number_exp<\
|
||||
detail::function\
|
||||
, detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type> \
|
||||
, detail::big_number_exp<tag, A1, A2, A3> \
|
||||
, Arithmetic\
|
||||
> \
|
||||
>::type \
|
||||
func(const detail::big_number_exp<tag, A1, A2, A3>& arg, const Arithmetic& a)\
|
||||
{\
|
||||
return detail::big_number_exp<\
|
||||
detail::function\
|
||||
, detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type> \
|
||||
, detail::big_number_exp<tag, A1, A2, A3> \
|
||||
, Arithmetic\
|
||||
>(\
|
||||
detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type>() \
|
||||
, arg,\
|
||||
a\
|
||||
);\
|
||||
}\
|
||||
|
||||
|
||||
#define HETERO_BINARY_OP_FUNCTOR(func, Arg2)\
|
||||
namespace detail{\
|
||||
template <class Backend> \
|
||||
struct BOOST_JOIN(func, _funct)\
|
||||
{\
|
||||
void operator()(Backend& result, Backend const& arg, Arg2 a)const\
|
||||
{\
|
||||
using big_num_default_ops:: BOOST_JOIN(eval_,func);\
|
||||
BOOST_JOIN(eval_,func)(result, arg, a);\
|
||||
}\
|
||||
};\
|
||||
\
|
||||
}\
|
||||
\
|
||||
template <class tag, class A1, class A2, class A3> \
|
||||
detail::big_number_exp<\
|
||||
detail::function\
|
||||
, detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type> \
|
||||
, detail::big_number_exp<tag, A1, A2, A3> \
|
||||
, Arg2\
|
||||
> \
|
||||
func(const detail::big_number_exp<tag, A1, A2, A3>& arg, Arg2 const& a)\
|
||||
{\
|
||||
return detail::big_number_exp<\
|
||||
detail::function\
|
||||
, detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type> \
|
||||
, detail::big_number_exp<tag, A1, A2, A3> \
|
||||
, Arg2\
|
||||
>(\
|
||||
detail::BOOST_JOIN(func, _funct)<typename detail::backend_type<detail::big_number_exp<tag, A1, A2, A3> >::type>() \
|
||||
, arg, a \
|
||||
);\
|
||||
}\
|
||||
template <class Backend> \
|
||||
detail::big_number_exp<\
|
||||
detail::function\
|
||||
, detail::BOOST_JOIN(func, _funct)<Backend> \
|
||||
, big_number<Backend> \
|
||||
, Arg2\
|
||||
> \
|
||||
func(const big_number<Backend>& arg, Arg2 const& a)\
|
||||
{\
|
||||
return detail::big_number_exp<\
|
||||
detail::function\
|
||||
, detail::BOOST_JOIN(func, _funct)<Backend> \
|
||||
, big_number<Backend> \
|
||||
, Arg2\
|
||||
>(\
|
||||
detail::BOOST_JOIN(func, _funct)<Backend>() \
|
||||
, arg,\
|
||||
a\
|
||||
);\
|
||||
}\
|
||||
|
||||
UNARY_OP_FUNCTOR(abs)
|
||||
UNARY_OP_FUNCTOR(fabs)
|
||||
UNARY_OP_FUNCTOR(sqrt)
|
||||
UNARY_OP_FUNCTOR(floor)
|
||||
UNARY_OP_FUNCTOR(ceil)
|
||||
UNARY_OP_FUNCTOR(trunc)
|
||||
UNARY_OP_FUNCTOR(exp)
|
||||
UNARY_OP_FUNCTOR(log)
|
||||
UNARY_OP_FUNCTOR(cos)
|
||||
UNARY_OP_FUNCTOR(sin)
|
||||
UNARY_OP_FUNCTOR(tan)
|
||||
UNARY_OP_FUNCTOR(asin)
|
||||
UNARY_OP_FUNCTOR(acos)
|
||||
UNARY_OP_FUNCTOR(atan)
|
||||
UNARY_OP_FUNCTOR(cosh)
|
||||
UNARY_OP_FUNCTOR(sinh)
|
||||
UNARY_OP_FUNCTOR(tanh)
|
||||
|
||||
HETERO_BINARY_OP_FUNCTOR(ldexp, int)
|
||||
HETERO_BINARY_OP_FUNCTOR(frexp, int*)
|
||||
BINARY_OP_FUNCTOR(pow)
|
||||
BINARY_OP_FUNCTOR(fmod)
|
||||
|
||||
#undef BINARY_OP_FUNCTOR
|
||||
#undef UNARY_OP_FUNCTOR
|
||||
|
||||
}} // namespaces
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////
|
||||
// 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_
|
||||
|
||||
#ifndef BOOST_MATH_EFX_BACKEND_HPP
|
||||
#define BOOST_MATH_EFX_BACKEND_HPP
|
||||
|
||||
#include <boost/math/big_number/arithmetic_backend.hpp>
|
||||
#include <boost/e_float/e_float.hpp>
|
||||
#include <boost/e_float/e_float_complex.hpp>
|
||||
#include <boost/e_float/e_float_elementary_math.hpp>
|
||||
#include <fstream>
|
||||
|
||||
namespace boost{
|
||||
namespace math{
|
||||
|
||||
typedef big_number<arithmetic_backend<efx::e_float> > e_float;
|
||||
|
||||
template<>
|
||||
inline void arithmetic_backend<efx::e_float>::negate()
|
||||
{
|
||||
m_value.negate();
|
||||
}
|
||||
template<>
|
||||
inline std::string arithmetic_backend<efx::e_float>::str(unsigned digits, bool scientific)const
|
||||
{
|
||||
std::fstream os;
|
||||
os << std::setprecision(digits ? digits : efx::e_float::ef_digits + 5);
|
||||
if(scientific)
|
||||
os << std::scientific;
|
||||
std::string result;
|
||||
this->data().wr_string(result, os);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline void eval_abs(arithmetic_backend<efx::e_float>& result, const arithmetic_backend<efx::e_float>& arg)
|
||||
{
|
||||
result.data() = ef::fabs(arg.data());
|
||||
}
|
||||
|
||||
inline void eval_fabs(arithmetic_backend<efx::e_float>& result, const arithmetic_backend<efx::e_float>& arg)
|
||||
{
|
||||
result.data() = ef::fabs(arg.data());
|
||||
}
|
||||
|
||||
inline bool is_zero(const arithmetic_backend<efx::e_float>& val)
|
||||
{
|
||||
return val.data().iszero();
|
||||
}
|
||||
inline int get_sign(const arithmetic_backend<efx::e_float>& val)
|
||||
{
|
||||
return val.data().isneg() ? -1 : val.data().iszero() ? 0 : 1;
|
||||
}
|
||||
|
||||
inline void convert_to(boost::uintmax_t* result, const arithmetic_backend<efx::e_float>& val)
|
||||
{
|
||||
*result = val.data().extract_unsigned_long_long();
|
||||
}
|
||||
inline void convert_to(boost::intmax_t* result, const arithmetic_backend<efx::e_float>& val)
|
||||
{
|
||||
*result = val.data().extract_signed_long_long();
|
||||
}
|
||||
inline void convert_to(double* result, const arithmetic_backend<efx::e_float>& val)
|
||||
{
|
||||
*result = val.data().extract_double();
|
||||
}
|
||||
inline void convert_to(long double* result, const arithmetic_backend<efx::e_float>& val)
|
||||
{
|
||||
*result = val.data().extract_long_double();
|
||||
}
|
||||
inline int eval_fpclassify(const arithmetic_backend<efx::e_float>& val)
|
||||
{
|
||||
return val.data().isinf() ? FP_INFINITE : val.data().isnan() ? FP_NAN : val.data().iszero() ? FP_ZERO : FP_NORMAL;
|
||||
}
|
||||
|
||||
|
||||
}} // namespaces
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,952 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// 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_MPFR_HPP
|
||||
#define BOOST_MATH_BN_MPFR_HPP
|
||||
|
||||
#include <boost/math/big_number.hpp>
|
||||
#include <boost/math/special_functions/fpclassify.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/math/bindings/detail/big_lanczos.hpp>
|
||||
#include <mpfr.h>
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
namespace boost{ namespace math{
|
||||
|
||||
template <unsigned digits10>
|
||||
struct mpfr_real_backend;
|
||||
|
||||
namespace detail{
|
||||
|
||||
long get_default_precision() { return 50; }
|
||||
|
||||
template <unsigned digits10>
|
||||
struct mpfr_real_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> real_types;
|
||||
|
||||
mpfr_real_imp(){}
|
||||
|
||||
mpfr_real_imp(const mpfr_real_imp& o)
|
||||
{
|
||||
mpfr_init2(m_data, (((digits10 ? digits10 : get_default_precision()) + 1) * 1000L) / 301L);
|
||||
mpfr_set(m_data, o.m_data, GMP_RNDN);
|
||||
}
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
mpfr_real_imp(mpfr_real_imp&& o)
|
||||
{
|
||||
m_data[0] = o.m_data[0];
|
||||
o.m_data[0]._mpfr_d = 0;
|
||||
}
|
||||
#endif
|
||||
mpfr_real_imp& operator = (const mpfr_real_imp& o)
|
||||
{
|
||||
mpfr_set(m_data, o.m_data, GMP_RNDN);
|
||||
return *this;
|
||||
}
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
mpfr_real_imp& operator = (mpfr_real_imp&& o)
|
||||
{
|
||||
mpfr_swap(m_data, o.m_data);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
mpfr_real_imp& operator = (boost::uintmax_t i)
|
||||
{
|
||||
boost::uintmax_t mask = ((1uLL << std::numeric_limits<unsigned>::digits) - 1);
|
||||
unsigned shift = 0;
|
||||
mpfr_t t;
|
||||
mpfr_init2(t, (std::max)(static_cast<unsigned>(std::numeric_limits<boost::uintmax_t>::digits), static_cast<unsigned>(((digits10 + 1) * 1000L) / 301L)));
|
||||
mpfr_set_ui(m_data, 0, GMP_RNDN);
|
||||
while(i)
|
||||
{
|
||||
mpfr_set_ui(t, static_cast<unsigned>(i & mask), GMP_RNDN);
|
||||
if(shift)
|
||||
mpfr_mul_2exp(t, t, shift, GMP_RNDN);
|
||||
mpfr_add(m_data, m_data, t, GMP_RNDN);
|
||||
shift += std::numeric_limits<unsigned>::digits;
|
||||
i >>= std::numeric_limits<unsigned>::digits;
|
||||
}
|
||||
mpfr_clear(t);
|
||||
return *this;
|
||||
}
|
||||
mpfr_real_imp& operator = (boost::intmax_t i)
|
||||
{
|
||||
bool neg = i < 0;
|
||||
*this = static_cast<boost::uintmax_t>(std::abs(i));
|
||||
if(neg)
|
||||
mpfr_neg(m_data, m_data, GMP_RNDN);
|
||||
return *this;
|
||||
}
|
||||
mpfr_real_imp& operator = (unsigned long i)
|
||||
{
|
||||
mpfr_set_ui(m_data, i, GMP_RNDN);
|
||||
return *this;
|
||||
}
|
||||
mpfr_real_imp& operator = (long i)
|
||||
{
|
||||
mpfr_set_si(m_data, i, GMP_RNDN);
|
||||
return *this;
|
||||
}
|
||||
mpfr_real_imp& operator = (double d)
|
||||
{
|
||||
mpfr_set_d(m_data, d, GMP_RNDN);
|
||||
return *this;
|
||||
}
|
||||
mpfr_real_imp& operator = (long double a)
|
||||
{
|
||||
using std::frexp;
|
||||
using std::ldexp;
|
||||
using std::floor;
|
||||
|
||||
if (a == 0) {
|
||||
mpfr_set_si(m_data, 0, GMP_RNDN);
|
||||
return *this;
|
||||
}
|
||||
|
||||
if (a == 1) {
|
||||
mpfr_set_si(m_data, 1, GMP_RNDN);
|
||||
return *this;
|
||||
}
|
||||
|
||||
BOOST_ASSERT(!(boost::math::isinf)(a));
|
||||
BOOST_ASSERT(!(boost::math::isnan)(a));
|
||||
|
||||
int e;
|
||||
long double f, term;
|
||||
mpfr_init_set_ui(m_data, 0u, GMP_RNDN);
|
||||
|
||||
f = frexp(a, &e);
|
||||
|
||||
static const int shift = std::numeric_limits<int>::digits - 1;
|
||||
|
||||
while(f)
|
||||
{
|
||||
// extract int sized bits from f:
|
||||
f = ldexp(f, shift);
|
||||
term = floor(f);
|
||||
e -= shift;
|
||||
mpfr_mul_2exp(m_data, m_data, shift, GMP_RNDN);
|
||||
if(term > 0)
|
||||
mpfr_add_ui(m_data, m_data, static_cast<unsigned>(term), GMP_RNDN);
|
||||
else
|
||||
mpfr_sub_ui(m_data, m_data, static_cast<unsigned>(-term), GMP_RNDN);
|
||||
f -= term;
|
||||
}
|
||||
if(e > 0)
|
||||
mpfr_mul_2exp(m_data, m_data, e, GMP_RNDN);
|
||||
else if(e < 0)
|
||||
mpfr_div_2exp(m_data, m_data, -e, GMP_RNDN);
|
||||
return *this;
|
||||
}
|
||||
mpfr_real_imp& operator = (const char* s)
|
||||
{
|
||||
mpfr_set_str(m_data, s, 10, GMP_RNDN);
|
||||
return *this;
|
||||
}
|
||||
void swap(mpfr_real_imp& o)
|
||||
{
|
||||
mpfr_swap(m_data, o.m_data);
|
||||
}
|
||||
std::string str(unsigned digits, bool scientific)const
|
||||
{
|
||||
std::string result;
|
||||
mp_exp_t e;
|
||||
char* ps = mpfr_get_str (0, &e, 10, digits, m_data, GMP_RNDN);
|
||||
std::ptrdiff_t sl = std::strlen(ps);
|
||||
unsigned chars = sl;
|
||||
if(sl == 0)
|
||||
return "0";
|
||||
while(ps[chars-1] == '0')
|
||||
--chars;
|
||||
if(*ps == '-')
|
||||
--chars; // number of digits excluding sign.
|
||||
if(chars == 0)
|
||||
return "0";
|
||||
if(!scientific
|
||||
&& (chars <= std::numeric_limits<boost::uintmax_t>::digits10 + 1)
|
||||
&& (e >= (int)chars)
|
||||
&& (chars <= std::numeric_limits<boost::uintmax_t>::digits10 + 1))
|
||||
{
|
||||
result.assign(ps, (*ps == '-' ? chars+1 : chars));
|
||||
result.append(e-chars, '0');
|
||||
}
|
||||
else
|
||||
{
|
||||
result = ps;
|
||||
if(ps[0] == '-')
|
||||
result.insert(2, 1, '.');
|
||||
else
|
||||
result.insert(1, 1, '.');
|
||||
--e;
|
||||
if(e)
|
||||
result += "e" + lexical_cast<std::string>(e);
|
||||
}
|
||||
mpfr_free_str(ps);
|
||||
return result;
|
||||
}
|
||||
~mpfr_real_imp()
|
||||
{
|
||||
if(m_data[0]._mpfr_d)
|
||||
mpfr_clear(m_data);
|
||||
}
|
||||
void negate()
|
||||
{
|
||||
mpfr_neg(m_data, m_data, GMP_RNDN);
|
||||
}
|
||||
int compare(const mpfr_real_backend<digits10>& o)const
|
||||
{
|
||||
return mpfr_cmp(m_data, o.m_data);
|
||||
}
|
||||
int compare(long i)const
|
||||
{
|
||||
return mpfr_cmp_si(m_data, i);
|
||||
}
|
||||
int compare(unsigned long i)const
|
||||
{
|
||||
return mpfr_cmp_ui(m_data, i);
|
||||
}
|
||||
template <class V>
|
||||
int compare(V v)const
|
||||
{
|
||||
mpfr_real_backend<digits10> d;
|
||||
d = v;
|
||||
return compare(d);
|
||||
}
|
||||
mpfr_t& data() { return m_data; }
|
||||
const mpfr_t& data()const { return m_data; }
|
||||
protected:
|
||||
mpfr_t m_data;
|
||||
static unsigned& get_default_precision()
|
||||
{
|
||||
static unsigned val = 50;
|
||||
return val;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template <unsigned digits10>
|
||||
struct mpfr_real_backend : public detail::mpfr_real_imp<digits10>
|
||||
{
|
||||
mpfr_real_backend()
|
||||
{
|
||||
mpfr_init2(this->m_data, ((digits10 + 1) * 1000L) / 301L);
|
||||
}
|
||||
mpfr_real_backend(const mpfr_real_backend& o) : detail::mpfr_real_imp<digits10>(o) {}
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
mpfr_real_backend(mpfr_real_backend&& o) : detail::mpfr_real_imp<digits10>(o) {}
|
||||
#endif
|
||||
mpfr_real_backend& operator=(const mpfr_real_backend& o)
|
||||
{
|
||||
*static_cast<detail::mpfr_real_imp<digits10>*>(this) = static_cast<detail::mpfr_real_imp<digits10> const&>(o);
|
||||
return *this;
|
||||
}
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
mpfr_real_backend& operator=(mpfr_real_backend&& o)
|
||||
{
|
||||
*static_cast<detail::mpfr_real_imp<digits10>*>(this) = static_cast<detail::mpfr_real_imp<digits10>&&>(o);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
template <class V>
|
||||
mpfr_real_backend& operator=(const V& v)
|
||||
{
|
||||
*static_cast<detail::mpfr_real_imp<digits10>*>(this) = v;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct mpfr_real_backend<0> : public detail::mpfr_real_imp<0>
|
||||
{
|
||||
mpfr_real_backend()
|
||||
{
|
||||
mpfr_init2(this->m_data, ((get_default_precision() + 1) * 1000L) / 301L);
|
||||
}
|
||||
mpfr_real_backend(unsigned digits10)
|
||||
{
|
||||
mpfr_init2(this->m_data, ((digits10 + 1) * 1000L) / 301L);
|
||||
}
|
||||
mpfr_real_backend(const mpfr_real_backend& o) : detail::mpfr_real_imp<0>(o) {}
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
mpfr_real_backend(mpfr_real_backend&& o) : detail::mpfr_real_imp<0>(o) {}
|
||||
#endif
|
||||
mpfr_real_backend(const mpfr_real_backend& o, unsigned digits10)
|
||||
{
|
||||
mpfr_init2(this->m_data, ((digits10 + 1) * 1000L) / 301L);
|
||||
*this = o;
|
||||
}
|
||||
|
||||
mpfr_real_backend& operator=(const mpfr_real_backend& o)
|
||||
{
|
||||
*static_cast<detail::mpfr_real_imp<0>*>(this) = static_cast<detail::mpfr_real_imp<0> const&>(o);
|
||||
return *this;
|
||||
}
|
||||
#ifndef BOOST_NO_RVALUE_REFERENCES
|
||||
mpfr_real_backend& operator=(mpfr_real_backend&& o)
|
||||
{
|
||||
*static_cast<detail::mpfr_real_imp<0>*>(this) = static_cast<detail::mpfr_real_imp<0> &&>(o);
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
template <class V>
|
||||
mpfr_real_backend& operator=(const V& v)
|
||||
{
|
||||
*static_cast<detail::mpfr_real_imp<0>*>(this) = v;
|
||||
return *this;
|
||||
}
|
||||
static unsigned default_precision()
|
||||
{
|
||||
return get_default_precision();
|
||||
}
|
||||
static void default_precision(unsigned v)
|
||||
{
|
||||
get_default_precision() = v;
|
||||
}
|
||||
unsigned precision()const
|
||||
{
|
||||
return mpfr_get_prec(this->m_data) * 301L / 1000 - 1;
|
||||
}
|
||||
void precision(unsigned digits10)
|
||||
{
|
||||
mpfr_set_prec(this->m_data, (digits10 + 1) * 1000L / 301);
|
||||
}
|
||||
};
|
||||
|
||||
template <unsigned digits10>
|
||||
inline void add(mpfr_real_backend<digits10>& result, const mpfr_real_backend<digits10>& o)
|
||||
{
|
||||
mpfr_add(result.data(), result.data(), o.data(), GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void subtract(mpfr_real_backend<digits10>& result, const mpfr_real_backend<digits10>& o)
|
||||
{
|
||||
mpfr_sub(result.data(), result.data(), o.data(), GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void multiply(mpfr_real_backend<digits10>& result, const mpfr_real_backend<digits10>& o)
|
||||
{
|
||||
mpfr_mul(result.data(), result.data(), o.data(), GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void divide(mpfr_real_backend<digits10>& result, const mpfr_real_backend<digits10>& o)
|
||||
{
|
||||
mpfr_div(result.data(), result.data(), o.data(), GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void add(mpfr_real_backend<digits10>& result, unsigned long i)
|
||||
{
|
||||
mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void subtract(mpfr_real_backend<digits10>& result, unsigned long i)
|
||||
{
|
||||
mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void multiply(mpfr_real_backend<digits10>& result, unsigned long i)
|
||||
{
|
||||
mpfr_mul_ui(result.data(), result.data(), i, GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void divide(mpfr_real_backend<digits10>& result, unsigned long i)
|
||||
{
|
||||
mpfr_div_ui(result.data(), result.data(), i, GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void add(mpfr_real_backend<digits10>& result, long i)
|
||||
{
|
||||
if(i > 0)
|
||||
mpfr_add_ui(result.data(), result.data(), i, GMP_RNDN);
|
||||
else
|
||||
mpfr_sub_ui(result.data(), result.data(), std::abs(i), GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void subtract(mpfr_real_backend<digits10>& result, long i)
|
||||
{
|
||||
if(i > 0)
|
||||
mpfr_sub_ui(result.data(), result.data(), i, GMP_RNDN);
|
||||
else
|
||||
mpfr_add_ui(result.data(), result.data(), std::abs(i), GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void multiply(mpfr_real_backend<digits10>& result, long i)
|
||||
{
|
||||
mpfr_mul_ui(result.data(), result.data(), std::abs(i), GMP_RNDN);
|
||||
if(i < 0)
|
||||
mpfr_neg(result.data(), result.data(), GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void divide(mpfr_real_backend<digits10>& result, long i)
|
||||
{
|
||||
mpfr_div_ui(result.data(), result.data(), std::abs(i), GMP_RNDN);
|
||||
if(i < 0)
|
||||
mpfr_neg(result.data(), result.data(), GMP_RNDN);
|
||||
}
|
||||
//
|
||||
// Specialised 3 arg versions of the basic operators:
|
||||
//
|
||||
template <unsigned digits10>
|
||||
inline void add(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, const mpfr_real_backend<digits10>& y)
|
||||
{
|
||||
mpfr_add(a.data(), x.data(), y.data(), GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void add(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, unsigned long y)
|
||||
{
|
||||
mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void add(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, long y)
|
||||
{
|
||||
if(y < 0)
|
||||
mpfr_sub_ui(a.data(), x.data(), -y, GMP_RNDN);
|
||||
else
|
||||
mpfr_add_ui(a.data(), x.data(), y, GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void add(mpfr_real_backend<digits10>& a, unsigned long x, const mpfr_real_backend<digits10>& y)
|
||||
{
|
||||
mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void add(mpfr_real_backend<digits10>& a, long x, const mpfr_real_backend<digits10>& y)
|
||||
{
|
||||
if(x < 0)
|
||||
{
|
||||
mpfr_ui_sub(a.data(), -x, y.data(), GMP_RNDN);
|
||||
mpfr_neg(a.data(), a.data(), GMP_RNDN);
|
||||
}
|
||||
else
|
||||
mpfr_add_ui(a.data(), y.data(), x, GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void subtract(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, const mpfr_real_backend<digits10>& y)
|
||||
{
|
||||
mpfr_sub(a.data(), x.data(), y.data(), GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void subtract(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, unsigned long y)
|
||||
{
|
||||
mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void subtract(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, long y)
|
||||
{
|
||||
if(y < 0)
|
||||
mpfr_add_ui(a.data(), x.data(), -y, GMP_RNDN);
|
||||
else
|
||||
mpfr_sub_ui(a.data(), x.data(), y, GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void subtract(mpfr_real_backend<digits10>& a, unsigned long x, const mpfr_real_backend<digits10>& y)
|
||||
{
|
||||
mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void subtract(mpfr_real_backend<digits10>& a, long x, const mpfr_real_backend<digits10>& y)
|
||||
{
|
||||
if(x < 0)
|
||||
{
|
||||
mpfr_add_ui(a.data(), y.data(), -x, GMP_RNDN);
|
||||
mpfr_neg(a.data(), a.data(), GMP_RNDN);
|
||||
}
|
||||
else
|
||||
mpfr_ui_sub(a.data(), x, y.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned digits10>
|
||||
inline void multiply(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, const mpfr_real_backend<digits10>& y)
|
||||
{
|
||||
mpfr_mul(a.data(), x.data(), y.data(), GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void multiply(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, unsigned long y)
|
||||
{
|
||||
mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void multiply(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, long y)
|
||||
{
|
||||
if(y < 0)
|
||||
{
|
||||
mpfr_mul_ui(a.data(), x.data(), -y, GMP_RNDN);
|
||||
a.negate();
|
||||
}
|
||||
else
|
||||
mpfr_mul_ui(a.data(), x.data(), y, GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void multiply(mpfr_real_backend<digits10>& a, unsigned long x, const mpfr_real_backend<digits10>& y)
|
||||
{
|
||||
mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void multiply(mpfr_real_backend<digits10>& a, long x, const mpfr_real_backend<digits10>& y)
|
||||
{
|
||||
if(x < 0)
|
||||
{
|
||||
mpfr_mul_ui(a.data(), y.data(), -x, GMP_RNDN);
|
||||
mpfr_neg(a.data(), a.data(), GMP_RNDN);
|
||||
}
|
||||
else
|
||||
mpfr_mul_ui(a.data(), y.data(), x, GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned digits10>
|
||||
inline void divide(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, const mpfr_real_backend<digits10>& y)
|
||||
{
|
||||
mpfr_div(a.data(), x.data(), y.data(), GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void divide(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, unsigned long y)
|
||||
{
|
||||
mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void divide(mpfr_real_backend<digits10>& a, const mpfr_real_backend<digits10>& x, long y)
|
||||
{
|
||||
if(y < 0)
|
||||
{
|
||||
mpfr_div_ui(a.data(), x.data(), -y, GMP_RNDN);
|
||||
a.negate();
|
||||
}
|
||||
else
|
||||
mpfr_div_ui(a.data(), x.data(), y, GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void divide(mpfr_real_backend<digits10>& a, unsigned long x, const mpfr_real_backend<digits10>& y)
|
||||
{
|
||||
mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void divide(mpfr_real_backend<digits10>& a, long x, const mpfr_real_backend<digits10>& y)
|
||||
{
|
||||
if(x < 0)
|
||||
{
|
||||
mpfr_ui_div(a.data(), -x, y.data(), GMP_RNDN);
|
||||
mpfr_neg(a.data(), a.data(), GMP_RNDN);
|
||||
}
|
||||
else
|
||||
mpfr_ui_div(a.data(), x, y.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned digits10>
|
||||
inline bool is_zero(const mpfr_real_backend<digits10>& val)
|
||||
{
|
||||
return 0 != mpfr_zero_p(val.data());
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline int get_sign(const mpfr_real_backend<digits10>& val)
|
||||
{
|
||||
return mpfr_sgn(val.data());
|
||||
}
|
||||
|
||||
template <unsigned digits10>
|
||||
inline void convert_to(unsigned long* result, const mpfr_real_backend<digits10>& val)
|
||||
{
|
||||
*result = mpfr_get_ui(val.data(), GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void convert_to(long* result, const mpfr_real_backend<digits10>& val)
|
||||
{
|
||||
*result = mpfr_get_si(val.data(), GMP_RNDN);
|
||||
}
|
||||
#ifdef _MPFR_H_HAVE_INTMAX_T
|
||||
template <unsigned digits10>
|
||||
inline void convert_to(boost::uintmax_t* result, const mpfr_real_backend<digits10>& val)
|
||||
{
|
||||
*result = mpfr_get_uj(val.data(), GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void convert_to(boost::intmax_t* result, const mpfr_real_backend<digits10>& val)
|
||||
{
|
||||
*result = mpfr_get_sj(val.data(), GMP_RNDN);
|
||||
}
|
||||
#endif
|
||||
template <unsigned digits10>
|
||||
inline void convert_to(double* result, const mpfr_real_backend<digits10>& val)
|
||||
{
|
||||
*result = mpfr_get_d(val.data(), GMP_RNDN);
|
||||
}
|
||||
template <unsigned digits10>
|
||||
inline void convert_to(long double* result, const mpfr_real_backend<digits10>& val)
|
||||
{
|
||||
*result = mpfr_get_ld(val.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
//
|
||||
// Native non-member operations:
|
||||
//
|
||||
template <unsigned Digits10>
|
||||
inline void eval_sqrt(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& val)
|
||||
{
|
||||
mpfr_sqrt(result.data(), val.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline void eval_abs(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& val)
|
||||
{
|
||||
mpfr_abs(result.data(), val.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline void eval_fabs(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& val)
|
||||
{
|
||||
mpfr_abs(result.data(), val.data(), GMP_RNDN);
|
||||
}
|
||||
template <unsigned Digits10>
|
||||
inline void eval_ceil(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& val)
|
||||
{
|
||||
mpfr_ceil(result.data(), val.data());
|
||||
}
|
||||
template <unsigned Digits10>
|
||||
inline void eval_floor(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& val)
|
||||
{
|
||||
mpfr_floor(result.data(), val.data());
|
||||
}
|
||||
template <unsigned Digits10>
|
||||
inline void eval_trunc(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& val)
|
||||
{
|
||||
mpfr_trunc(result.data(), val.data());
|
||||
}
|
||||
template <unsigned Digits10>
|
||||
inline void eval_ldexp(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& val, long e)
|
||||
{
|
||||
if(e > 0)
|
||||
mpfr_mul_2exp(result.data(), val.data(), e, GMP_RNDN);
|
||||
else if(e < 0)
|
||||
mpfr_div_2exp(result.data(), val.data(), -e, GMP_RNDN);
|
||||
}
|
||||
template <unsigned Digits10>
|
||||
inline void eval_frexp(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& val, int* e)
|
||||
{
|
||||
long v;
|
||||
mpfr_get_d_2exp(&v, val.data(), GMP_RNDN);
|
||||
*e = v;
|
||||
eval_ldexp(result, val, -v);
|
||||
}
|
||||
template <unsigned Digits10>
|
||||
inline void eval_frexp(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& val, long* e)
|
||||
{
|
||||
mpfr_get_d_2exp(e, val.data(), GMP_RNDN);
|
||||
return eval_ldexp(result, val, -*e);
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline int eval_fpclassify(const mpfr_real_backend<Digits10>& val)
|
||||
{
|
||||
return mpfr_inf_p(val.data()) ? FP_INFINITE : mpfr_nan_p(val.data()) ? FP_NAN : mpfr_zero_p(val.data()) ? FP_ZERO : FP_NORMAL;
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline void eval_pow(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& b, const mpfr_real_backend<Digits10>& e)
|
||||
{
|
||||
mpfr_pow(result.data(), b.data(), e.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10, class Integer>
|
||||
inline typename enable_if<mpl::and_<is_signed<Integer>, mpl::bool_<sizeof(Integer) <= sizeof(long)> > >::type eval_pow(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& b, const Integer& e)
|
||||
{
|
||||
mpfr_pow_si(result.data(), b.data(), e, GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10, class Integer>
|
||||
inline typename enable_if<mpl::and_<is_unsigned<Integer>, mpl::bool_<sizeof(Integer) <= sizeof(long)> > >::type eval_pow(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& b, const Integer& e)
|
||||
{
|
||||
mpfr_pow_ui(result.data(), b.data(), e, GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline void eval_exp(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
|
||||
{
|
||||
mpfr_exp(result.data(), arg.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline void eval_log(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
|
||||
{
|
||||
mpfr_log(result.data(), arg.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline void eval_sin(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
|
||||
{
|
||||
mpfr_sin(result.data(), arg.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline void eval_cos(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
|
||||
{
|
||||
mpfr_cos(result.data(), arg.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline void eval_tan(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
|
||||
{
|
||||
mpfr_tan(result.data(), arg.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline void eval_asin(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
|
||||
{
|
||||
mpfr_asin(result.data(), arg.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline void eval_acos(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
|
||||
{
|
||||
mpfr_acos(result.data(), arg.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline void eval_atan(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
|
||||
{
|
||||
mpfr_atan(result.data(), arg.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline void eval_sinh(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
|
||||
{
|
||||
mpfr_sinh(result.data(), arg.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline void eval_cosh(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
|
||||
{
|
||||
mpfr_cosh(result.data(), arg.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
template <unsigned Digits10>
|
||||
inline void eval_tanh(mpfr_real_backend<Digits10>& result, const mpfr_real_backend<Digits10>& arg)
|
||||
{
|
||||
mpfr_tanh(result.data(), arg.data(), GMP_RNDN);
|
||||
}
|
||||
|
||||
typedef big_number<mpfr_real_backend<50> > mpfr_real_50;
|
||||
typedef big_number<mpfr_real_backend<100> > mpfr_real_100;
|
||||
typedef big_number<mpfr_real_backend<500> > mpfr_real_500;
|
||||
typedef big_number<mpfr_real_backend<1000> > mpfr_real_1000;
|
||||
typedef big_number<mpfr_real_backend<0> > mpfr_real;
|
||||
|
||||
namespace lanczos{
|
||||
|
||||
template<unsigned Digits10, class Policy>
|
||||
struct lanczos<big_number<mpfr_real_backend<Digits10> >, Policy>
|
||||
{
|
||||
typedef typename mpl::if_c<
|
||||
Digits10 <= 36,
|
||||
lanczos22UDT,
|
||||
typename mpl::if_c<
|
||||
Digits10 <= 50,
|
||||
lanczos31UDT,
|
||||
typename mpl::if_c<
|
||||
Digits10 <= 110,
|
||||
lanczos61UDT,
|
||||
undefined_lanczos
|
||||
>::type
|
||||
>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
} // namespace lanczos
|
||||
|
||||
|
||||
}} // namespaces
|
||||
|
||||
namespace std{
|
||||
|
||||
#ifdef BOOST_NO_NOEXCEPT
|
||||
# define noexcept
|
||||
#endif
|
||||
|
||||
//
|
||||
// numeric_limits [partial] specializations for the types declared in this header:
|
||||
//
|
||||
template<unsigned Digits10>
|
||||
class numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<Digits10> > >
|
||||
{
|
||||
typedef boost::math::big_number<boost::math::mpfr_real_backend<Digits10> > number_type;
|
||||
public:
|
||||
BOOST_STATIC_CONSTEXPR bool is_specialized = true;
|
||||
BOOST_STATIC_CONSTEXPR number_type (min)() noexcept
|
||||
{
|
||||
initializer.do_nothing();
|
||||
static std::pair<bool, number_type> value;
|
||||
if(!value.first)
|
||||
{
|
||||
value.first = true;
|
||||
value.second = 0.5;
|
||||
mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), -mpfr_get_emin(), GMP_RNDN);
|
||||
}
|
||||
return value.second;
|
||||
}
|
||||
BOOST_STATIC_CONSTEXPR number_type (max)() noexcept
|
||||
{
|
||||
initializer.do_nothing();
|
||||
static std::pair<bool, number_type> value;
|
||||
if(!value.first)
|
||||
{
|
||||
value.first = true;
|
||||
value.second = 0.5;
|
||||
mpfr_mul_2exp(value.second.backend().data(), value.second.backend().data(), mpfr_get_emax(), GMP_RNDN);
|
||||
}
|
||||
return value.second;
|
||||
}
|
||||
BOOST_STATIC_CONSTEXPR number_type lowest() noexcept
|
||||
{
|
||||
return -(max)();
|
||||
}
|
||||
BOOST_STATIC_CONSTEXPR int digits = static_cast<int>(((Digits10 + 1) * 1000L) / 301L);
|
||||
BOOST_STATIC_CONSTEXPR int digits10 = Digits10;
|
||||
// Is this really correct???
|
||||
BOOST_STATIC_CONSTEXPR int max_digits10 = Digits10 + 1;
|
||||
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;
|
||||
BOOST_STATIC_CONSTEXPR number_type epsilon() noexcept
|
||||
{
|
||||
initializer.do_nothing();
|
||||
static std::pair<bool, number_type> value;
|
||||
if(!value.first)
|
||||
{
|
||||
value.first = true;
|
||||
value.second = 1;
|
||||
mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), std::numeric_limits<number_type>::digits - 1, GMP_RNDN);
|
||||
}
|
||||
return value.second;
|
||||
}
|
||||
// What value should this be????
|
||||
BOOST_STATIC_CONSTEXPR number_type round_error() noexcept
|
||||
{
|
||||
// returns epsilon/2
|
||||
initializer.do_nothing();
|
||||
static std::pair<bool, number_type> value;
|
||||
if(!value.first)
|
||||
{
|
||||
value.first = true;
|
||||
value.second = 1;
|
||||
mpfr_div_2exp(value.second.backend().data(), value.second.backend().data(), digits, GMP_RNDN);
|
||||
}
|
||||
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;
|
||||
BOOST_STATIC_CONSTEXPR number_type infinity() noexcept
|
||||
{
|
||||
// returns epsilon/2
|
||||
initializer.do_nothing();
|
||||
static std::pair<bool, number_type> value;
|
||||
if(!value.first)
|
||||
{
|
||||
value.first = true;
|
||||
value.second = 1;
|
||||
mpfr_set_inf(value.second.backend().data(), 1);
|
||||
}
|
||||
return value.second;
|
||||
}
|
||||
BOOST_STATIC_CONSTEXPR number_type quiet_NaN() noexcept
|
||||
{
|
||||
// returns epsilon/2
|
||||
initializer.do_nothing();
|
||||
static std::pair<bool, number_type> value;
|
||||
if(!value.first)
|
||||
{
|
||||
value.first = true;
|
||||
value.second = 1;
|
||||
mpfr_set_nan(value.second.backend().data());
|
||||
}
|
||||
return value.second;
|
||||
}
|
||||
BOOST_STATIC_CONSTEXPR number_type signaling_NaN() noexcept
|
||||
{
|
||||
return number_type(0);
|
||||
}
|
||||
BOOST_STATIC_CONSTEXPR number_type denorm_min() noexcept { 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::math::big_number<boost::math::mpfr_real_backend<digits10> > >::epsilon();
|
||||
std::numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<digits10> > >::round_error();
|
||||
(std::numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<digits10> > >::min)();
|
||||
(std::numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<digits10> > >::max)();
|
||||
std::numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<digits10> > >::infinity();
|
||||
std::numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<digits10> > >::quiet_NaN();
|
||||
}
|
||||
void do_nothing()const{}
|
||||
};
|
||||
static const data_initializer initializer;
|
||||
};
|
||||
|
||||
template<unsigned Digits10>
|
||||
const typename numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<Digits10> > >::data_initializer numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<Digits10> > >::initializer;
|
||||
|
||||
template<>
|
||||
class numeric_limits<boost::math::big_number<boost::math::mpfr_real_backend<0> > >
|
||||
{
|
||||
typedef boost::math::big_number<boost::math::mpfr_real_backend<0> > number_type;
|
||||
public:
|
||||
BOOST_STATIC_CONSTEXPR bool is_specialized = false;
|
||||
BOOST_STATIC_CONSTEXPR number_type (min)() noexcept { return number_type(0); }
|
||||
BOOST_STATIC_CONSTEXPR number_type (max)() noexcept { return number_type(0); }
|
||||
BOOST_STATIC_CONSTEXPR number_type lowest() noexcept { 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;
|
||||
BOOST_STATIC_CONSTEXPR number_type epsilon() noexcept { return number_type(0); }
|
||||
BOOST_STATIC_CONSTEXPR number_type round_error() noexcept { 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;
|
||||
BOOST_STATIC_CONSTEXPR number_type infinity() noexcept { return number_type(0); }
|
||||
BOOST_STATIC_CONSTEXPR number_type quiet_NaN() noexcept { return number_type(0); }
|
||||
BOOST_STATIC_CONSTEXPR number_type signaling_NaN() noexcept { return number_type(0); }
|
||||
BOOST_STATIC_CONSTEXPR number_type denorm_min() noexcept { 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;
|
||||
};
|
||||
|
||||
#ifdef noexcept
|
||||
#undef noexcept
|
||||
#endif
|
||||
|
||||
} // namespace std
|
||||
#endif
|
||||
@@ -1,293 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////
|
||||
// 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_
|
||||
|
||||
#ifndef BOOST_MATH_CONCEPTS_ER_HPP
|
||||
#define BOOST_MATH_CONCEPTS_ER_HPP
|
||||
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <cmath>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/lexical_cast.hpp>
|
||||
#include <boost/math/big_number.hpp>
|
||||
#include <boost/math/special_functions/trunc.hpp>
|
||||
|
||||
namespace boost{
|
||||
namespace math{
|
||||
namespace concepts{
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4244)
|
||||
#endif
|
||||
|
||||
struct big_number_backend_real_architype
|
||||
{
|
||||
typedef mpl::list<long long> signed_types;
|
||||
typedef mpl::list<unsigned long long> unsigned_types;
|
||||
typedef mpl::list<long double> real_types;
|
||||
|
||||
big_number_backend_real_architype()
|
||||
{
|
||||
std::cout << "Default construct" << std::endl;
|
||||
}
|
||||
big_number_backend_real_architype(const big_number_backend_real_architype& o)
|
||||
{
|
||||
std::cout << "Copy construct" << std::endl;
|
||||
m_value = o.m_value;
|
||||
}
|
||||
big_number_backend_real_architype& operator = (const big_number_backend_real_architype& o)
|
||||
{
|
||||
m_value = o.m_value;
|
||||
std::cout << "Assignment (" << m_value << ")" << std::endl;
|
||||
return *this;
|
||||
}
|
||||
big_number_backend_real_architype& operator = (boost::uintmax_t i)
|
||||
{
|
||||
m_value = i;
|
||||
std::cout << "UInt Assignment (" << i << ")" << std::endl;
|
||||
return *this;
|
||||
}
|
||||
big_number_backend_real_architype& operator = (boost::intmax_t i)
|
||||
{
|
||||
m_value = i;
|
||||
std::cout << "Int Assignment (" << i << ")" << std::endl;
|
||||
return *this;
|
||||
}
|
||||
big_number_backend_real_architype& operator = (long double d)
|
||||
{
|
||||
m_value = d;
|
||||
std::cout << "long double Assignment (" << d << ")" << std::endl;
|
||||
return *this;
|
||||
}
|
||||
big_number_backend_real_architype& operator = (const char* s)
|
||||
{
|
||||
m_value = boost::lexical_cast<double>(s);
|
||||
std::cout << "const char* Assignment (" << s << ")" << std::endl;
|
||||
return *this;
|
||||
}
|
||||
void swap(big_number_backend_real_architype& o)
|
||||
{
|
||||
std::cout << "Swapping (" << m_value << " with " << o.m_value << ")" << std::endl;
|
||||
std::swap(m_value, o.m_value);
|
||||
}
|
||||
std::string str(unsigned digits, bool scientific)const
|
||||
{
|
||||
std::stringstream ss;
|
||||
if(scientific)
|
||||
ss.setf(ss.scientific);
|
||||
if(digits)
|
||||
ss.precision(digits);
|
||||
else
|
||||
ss.precision(std::numeric_limits<long double>::digits10 + 2);
|
||||
boost::intmax_t i = m_value;
|
||||
boost::uintmax_t u = m_value;
|
||||
if(!scientific && m_value == i)
|
||||
ss << i;
|
||||
else if(!scientific && m_value == u)
|
||||
ss << u;
|
||||
else
|
||||
ss << m_value;
|
||||
std::string s = ss.str();
|
||||
std::cout << "Converting to string (" << s << ")" << std::endl;
|
||||
return s;
|
||||
}
|
||||
void negate()
|
||||
{
|
||||
std::cout << "Negating (" << m_value << ")" << std::endl;
|
||||
m_value = -m_value;
|
||||
}
|
||||
int compare(const big_number_backend_real_architype& o)const
|
||||
{
|
||||
std::cout << "Comparison" << std::endl;
|
||||
return m_value > o.m_value ? 1 : (m_value < o.m_value ? -1 : 0);
|
||||
}
|
||||
int compare(boost::intmax_t i)const
|
||||
{
|
||||
std::cout << "Comparison with int" << std::endl;
|
||||
return m_value > i ? 1 : (m_value < i ? -1 : 0);
|
||||
}
|
||||
int compare(boost::uintmax_t i)const
|
||||
{
|
||||
std::cout << "Comparison with unsigned" << std::endl;
|
||||
return m_value > i ? 1 : (m_value < i ? -1 : 0);
|
||||
}
|
||||
int compare(long double d)const
|
||||
{
|
||||
std::cout << "Comparison with long double" << std::endl;
|
||||
return m_value > d ? 1 : (m_value < d ? -1 : 0);
|
||||
}
|
||||
long double m_value;
|
||||
};
|
||||
|
||||
inline void add(big_number_backend_real_architype& result, const big_number_backend_real_architype& o)
|
||||
{
|
||||
std::cout << "Addition (" << result.m_value << " += " << o.m_value << ")" << std::endl;
|
||||
result.m_value += o.m_value;
|
||||
}
|
||||
inline void subtract(big_number_backend_real_architype& result, const big_number_backend_real_architype& o)
|
||||
{
|
||||
std::cout << "Subtraction (" << result.m_value << " -= " << o.m_value << ")" << std::endl;
|
||||
result.m_value -= o.m_value;
|
||||
}
|
||||
inline void multiply(big_number_backend_real_architype& result, const big_number_backend_real_architype& o)
|
||||
{
|
||||
std::cout << "Multiplication (" << result.m_value << " *= " << o.m_value << ")" << std::endl;
|
||||
result.m_value *= o.m_value;
|
||||
}
|
||||
inline void divide(big_number_backend_real_architype& result, const big_number_backend_real_architype& o)
|
||||
{
|
||||
std::cout << "Division (" << result.m_value << " /= " << o.m_value << ")" << std::endl;
|
||||
result.m_value /= o.m_value;
|
||||
}
|
||||
|
||||
inline void eval_frexp(big_number_backend_real_architype& result, const big_number_backend_real_architype& arg, int* exp)
|
||||
{
|
||||
result = std::frexp(arg.m_value, exp);
|
||||
}
|
||||
|
||||
inline void eval_ldexp(big_number_backend_real_architype& result, const big_number_backend_real_architype& arg, int exp)
|
||||
{
|
||||
result = std::ldexp(arg.m_value, exp);
|
||||
}
|
||||
|
||||
inline void eval_floor(big_number_backend_real_architype& result, const big_number_backend_real_architype& arg)
|
||||
{
|
||||
result = std::floor(arg.m_value);
|
||||
}
|
||||
|
||||
inline void eval_ceil(big_number_backend_real_architype& result, const big_number_backend_real_architype& arg)
|
||||
{
|
||||
result = std::ceil(arg.m_value);
|
||||
}
|
||||
|
||||
inline void eval_trunc(big_number_backend_real_architype& result, const big_number_backend_real_architype& arg)
|
||||
{
|
||||
result = boost::math::trunc(arg.m_value);
|
||||
}
|
||||
|
||||
inline void eval_sqrt(big_number_backend_real_architype& result, const big_number_backend_real_architype& arg)
|
||||
{
|
||||
result = std::sqrt(arg.m_value);
|
||||
}
|
||||
|
||||
inline void eval_abs(big_number_backend_real_architype& result, const big_number_backend_real_architype& arg)
|
||||
{
|
||||
result = std::abs(arg.m_value);
|
||||
}
|
||||
|
||||
inline void eval_fabs(big_number_backend_real_architype& result, const big_number_backend_real_architype& arg)
|
||||
{
|
||||
result = std::fabs(arg.m_value);
|
||||
}
|
||||
|
||||
inline int eval_fpclassify(const big_number_backend_real_architype& arg)
|
||||
{
|
||||
return boost::math::fpclassify(arg.m_value);
|
||||
}
|
||||
|
||||
inline void eval_pow(big_number_backend_real_architype& result, const big_number_backend_real_architype& b, const big_number_backend_real_architype& e)
|
||||
{
|
||||
result = std::pow(b.m_value, e.m_value);
|
||||
}
|
||||
|
||||
inline void eval_pow(big_number_backend_real_architype& result, const big_number_backend_real_architype& b, int e)
|
||||
{
|
||||
result = std::pow(b.m_value, e);
|
||||
}
|
||||
|
||||
inline void eval_exp(big_number_backend_real_architype& result, const big_number_backend_real_architype& arg)
|
||||
{
|
||||
result = std::exp(arg.m_value);
|
||||
}
|
||||
|
||||
inline void eval_log(big_number_backend_real_architype& result, const big_number_backend_real_architype& arg)
|
||||
{
|
||||
result = std::log(arg.m_value);
|
||||
}
|
||||
|
||||
inline void eval_sin(big_number_backend_real_architype& result, const big_number_backend_real_architype& arg)
|
||||
{
|
||||
result = std::sin(arg.m_value);
|
||||
}
|
||||
|
||||
inline void eval_cos(big_number_backend_real_architype& result, const big_number_backend_real_architype& arg)
|
||||
{
|
||||
result = std::cos(arg.m_value);
|
||||
}
|
||||
|
||||
inline void eval_tan(big_number_backend_real_architype& result, const big_number_backend_real_architype& arg)
|
||||
{
|
||||
result = std::tan(arg.m_value);
|
||||
}
|
||||
|
||||
inline void eval_asin(big_number_backend_real_architype& result, const big_number_backend_real_architype& arg)
|
||||
{
|
||||
result = std::asin(arg.m_value);
|
||||
}
|
||||
|
||||
inline void eval_acos(big_number_backend_real_architype& result, const big_number_backend_real_architype& arg)
|
||||
{
|
||||
result = std::acos(arg.m_value);
|
||||
}
|
||||
|
||||
inline void eval_atan(big_number_backend_real_architype& result, const big_number_backend_real_architype& arg)
|
||||
{
|
||||
result = std::atan(arg.m_value);
|
||||
}
|
||||
|
||||
inline void eval_sinh(big_number_backend_real_architype& result, const big_number_backend_real_architype& arg)
|
||||
{
|
||||
result = std::sinh(arg.m_value);
|
||||
}
|
||||
|
||||
inline void eval_cosh(big_number_backend_real_architype& result, const big_number_backend_real_architype& arg)
|
||||
{
|
||||
result = std::cosh(arg.m_value);
|
||||
}
|
||||
|
||||
inline void eval_tanh(big_number_backend_real_architype& result, const big_number_backend_real_architype& arg)
|
||||
{
|
||||
result = std::tanh(arg.m_value);
|
||||
}
|
||||
|
||||
typedef boost::math::big_number<big_number_backend_real_architype> big_number_real_architype;
|
||||
|
||||
}}} // namespaces
|
||||
|
||||
namespace std{
|
||||
|
||||
#ifdef BOOST_NO_NOEXCEPT
|
||||
# define noexcept
|
||||
#endif
|
||||
|
||||
template <>
|
||||
class numeric_limits<boost::math::concepts::big_number_real_architype> : public std::numeric_limits<long double>
|
||||
{
|
||||
typedef std::numeric_limits<long double> base_type;
|
||||
typedef boost::math::concepts::big_number_real_architype number_type;
|
||||
public:
|
||||
BOOST_STATIC_CONSTEXPR number_type (min)() noexcept { return (base_type::min)(); }
|
||||
BOOST_STATIC_CONSTEXPR number_type (max)() noexcept { return (base_type::max)(); }
|
||||
BOOST_STATIC_CONSTEXPR number_type lowest() noexcept { return -(max)(); }
|
||||
BOOST_STATIC_CONSTEXPR number_type epsilon() noexcept { return base_type::epsilon(); }
|
||||
BOOST_STATIC_CONSTEXPR number_type round_error() noexcept { return epsilon() / 2; }
|
||||
BOOST_STATIC_CONSTEXPR number_type infinity() noexcept { return base_type::infinity(); }
|
||||
BOOST_STATIC_CONSTEXPR number_type quiet_NaN() noexcept { return base_type::quiet_NaN(); }
|
||||
BOOST_STATIC_CONSTEXPR number_type signaling_NaN() noexcept { return base_type::signaling_NaN(); }
|
||||
BOOST_STATIC_CONSTEXPR number_type denorm_min() noexcept { return base_type::denorm_min(); }
|
||||
};
|
||||
|
||||
#ifdef BOOST_NO_NOEXCEPT
|
||||
# undef noexcept
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#ifdef BOOST_MSVC
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user