diff --git a/include/boost/math/big_number.hpp b/include/boost/math/big_number.hpp index 664aec72..b2f2612a 100644 --- a/include/boost/math/big_number.hpp +++ b/include/boost/math/big_number.hpp @@ -224,7 +224,6 @@ public: // big_number& operator++() { - BOOST_STATIC_ASSERT_MSG(is_extended_integer::value, "The increment operation is only valid for integer types"); using big_num_default_ops::increment; increment(m_backend); return *this; @@ -232,7 +231,6 @@ public: big_number& operator--() { - BOOST_STATIC_ASSERT_MSG(is_extended_integer::value, "The increment operation is only valid for integer types"); using big_num_default_ops::decrement; decrement(m_backend); return *this; @@ -240,7 +238,6 @@ public: big_number operator++(int) { - BOOST_STATIC_ASSERT_MSG(is_extended_integer::value, "The increment operation is only valid for integer types"); using big_num_default_ops::increment; self_type temp(*this); increment(m_backend); @@ -249,7 +246,6 @@ public: big_number operator--(int) { - BOOST_STATIC_ASSERT_MSG(is_extended_integer::value, "The increment operation is only valid for integer types"); using big_num_default_ops::decrement; self_type temp(*this); decrement(m_backend); @@ -439,6 +435,8 @@ public: template typename enable_if, int>::type compare(const V& o)const { + if(o == 0) + return get_sign(m_backend); return m_backend.compare(canonical_value(o)); } Backend& backend() @@ -1380,6 +1378,7 @@ private: static const Backend& canonical_value(const self_type& v){ return v.m_backend; } static const Backend& canonical_value(const self_type* v){ return v->m_backend; } static const Backend& canonical_value(self_type* v){ return v->m_backend; } + static const Backend& canonical_value(self_type& v){ return v.m_backend; } template static typename detail::canonical::type canonical_value(const V& v){ return v; } static typename detail::canonical::type canonical_value(const std::string& v){ return v.c_str(); } diff --git a/include/boost/math/big_number/default_ops.hpp b/include/boost/math/big_number/default_ops.hpp index ca14a806..da2df385 100644 --- a/include/boost/math/big_number/default_ops.hpp +++ b/include/boost/math/big_number/default_ops.hpp @@ -328,7 +328,7 @@ inline void convert_to(terminal* result, const B& backend) // Functions: // template -void eval_abs(T* result, const T& arg) +void eval_abs(T& result, const T& arg) { typedef typename T::signed_types type_list; typedef typename mpl::front::type front; @@ -337,7 +337,7 @@ void eval_abs(T* result, const T& arg) result->negate(); } template -void eval_fabs(T* result, const T& arg) +void eval_fabs(T& result, const T& arg) { typedef typename T::signed_types type_list; typedef typename mpl::front::type front; @@ -351,6 +351,26 @@ inline int eval_fpclassify(const Backend& arg) { return is_zero(arg) ? FP_ZERO : FP_NORMAL; } + +template +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. // @@ -828,6 +848,7 @@ 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 diff --git a/include/boost/math/big_number/gmp.hpp b/include/boost/math/big_number/gmp.hpp index cfb114aa..3c32b4ea 100644 --- a/include/boost/math/big_number/gmp.hpp +++ b/include/boost/math/big_number/gmp.hpp @@ -1225,6 +1225,14 @@ struct gmp_rational d = v; return compare(d); } + int compare(unsigned long v) + { + return mpq_cmp_ui(m_data, v, 1); + } + int compare(long v) + { + return mpq_cmp_si(m_data, v, 1); + } mpq_t& data() { return m_data; } const mpq_t& data()const { return m_data; } protected: @@ -1277,6 +1285,20 @@ inline void convert_to(double* result, const gmp_rational& val) *result = mpq_get_d(val.data()); } +inline void convert_to(long* result, const gmp_rational& val) +{ + double r; + convert_to(&r, val); + *result = r; +} + +inline void convert_to(unsigned long* result, const gmp_rational& val) +{ + double r; + convert_to(&r, val); + *result = r; +} + inline void eval_abs(gmp_rational& result, const gmp_rational& val) { mpq_abs(result.data(), val.data()); diff --git a/include/boost/math/big_number/mpfr.hpp b/include/boost/math/big_number/mpfr.hpp index 3020edf5..e03f05da 100644 --- a/include/boost/math/big_number/mpfr.hpp +++ b/include/boost/math/big_number/mpfr.hpp @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -739,6 +740,29 @@ typedef big_number > mpfr_real_500; typedef big_number > mpfr_real_1000; typedef big_number > mpfr_real; +namespace lanczos{ + +template +struct lanczos >, 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{ diff --git a/include/boost/math/concepts/big_number_architypes.hpp b/include/boost/math/concepts/big_number_architypes.hpp index 66d79fc4..26a7a4b6 100644 --- a/include/boost/math/concepts/big_number_architypes.hpp +++ b/include/boost/math/concepts/big_number_architypes.hpp @@ -188,6 +188,71 @@ 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_real_architype; }}} // namespaces diff --git a/math/test/test_arithmetic.cpp b/math/test/test_arithmetic.cpp index a8635716..fa795461 100644 --- a/math/test/test_arithmetic.cpp +++ b/math/test/test_arithmetic.cpp @@ -345,6 +345,18 @@ void test_negative_mixed(boost::mpl::true_ const&) Num n3 = 0; Num n4 = -20; Num n5 = -8; + BOOST_TEST((Real(n2) < 0) == true); + BOOST_TEST((Real(n2) <= 0) == true); + BOOST_TEST((Real(n2) > 0) == false); + BOOST_TEST((Real(n2) >= 0) == false); + BOOST_TEST((Real(n2) == 0) == false); + BOOST_TEST((Real(n2) != 0) == true); + BOOST_TEST((Real(n2) == n2) == true); + BOOST_TEST((Real(n2) != n2) == false); + BOOST_TEST((Real(n2) >= n2) == true); + BOOST_TEST((Real(n2) <= n2) == true); + BOOST_TEST((Real(n2) > n2) == false); + BOOST_TEST((Real(n2) < n2) == false); // Default construct: BOOST_TEST(Real(n1) == n1); BOOST_TEST(Real(n2) == n2); @@ -425,6 +437,18 @@ void test_mixed() Num n3 = 0; Num n4 = 20; Num n5 = 8; + BOOST_TEST((Real(n2) < 0) == false); + BOOST_TEST((Real(n2) <= 0) == false); + BOOST_TEST((Real(n2) > 0) == true); + BOOST_TEST((Real(n2) >= 0) == true); + BOOST_TEST((Real(n2) == 0) == false); + BOOST_TEST((Real(n2) != 0) == true); + BOOST_TEST((Real(n2) == n2) == true); + BOOST_TEST((Real(n2) != n2) == false); + BOOST_TEST((Real(n2) >= n2) == true); + BOOST_TEST((Real(n2) <= n2) == true); + BOOST_TEST((Real(n2) > n2) == false); + BOOST_TEST((Real(n2) < n2) == false); // Default construct: BOOST_TEST(Real(n1) == n1); BOOST_TEST(Real(n2) == n2);