Giant file and directory rename: changed directory name from math to multiprecision and updated code to match.

[SVN r74582]
This commit is contained in:
John Maddock
2011-09-26 17:03:55 +00:00
parent 440eb46de6
commit 94d6513d38
8 changed files with 0 additions and 6460 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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