From 050ae32c4438bbb00b0b4b2ab4aae00e552f94cb Mon Sep 17 00:00:00 2001 From: John Maddock Date: Wed, 16 Nov 2011 09:40:05 +0000 Subject: [PATCH] Add initial libtommath support. Fix use of noexcept. Remove dead files. [SVN r75505] --- config/Jamfile.v2 | 5 +- config/has_e_float.cpp | 17 - config/has_gcc_visibility.cpp | 13 - config/has_long_double_support.cpp | 10 - config/has_mpfr_class.cpp | 14 - config/has_mpreal.cpp | 14 - config/has_ntl_rr.cpp | 12 - config/{has_gmpxx.cpp => has_tommath.cpp} | 4 +- .../multiprecision/arithmetic_backend.hpp | 22 +- .../concepts/mp_number_architypes.hpp | 22 +- .../multiprecision/detail/mp_number_base.hpp | 6 + include/boost/multiprecision/e_float.hpp | 80 ---- include/boost/multiprecision/gmp.hpp | 83 ++-- include/boost/multiprecision/mpfr.hpp | 42 +- include/boost/multiprecision/tommath.hpp | 411 ++++++++++++++++++ test/Jamfile.v2 | 29 ++ test/test_arithmetic.cpp | 24 +- test/test_numeric_limits.cpp | 9 +- 18 files changed, 564 insertions(+), 253 deletions(-) delete mode 100644 config/has_e_float.cpp delete mode 100644 config/has_gcc_visibility.cpp delete mode 100644 config/has_long_double_support.cpp delete mode 100644 config/has_mpfr_class.cpp delete mode 100644 config/has_mpreal.cpp delete mode 100644 config/has_ntl_rr.cpp rename config/{has_gmpxx.cpp => has_tommath.cpp} (78%) delete mode 100644 include/boost/multiprecision/e_float.hpp create mode 100644 include/boost/multiprecision/tommath.hpp diff --git a/config/Jamfile.v2 b/config/Jamfile.v2 index a307db12..91f9cbb3 100644 --- a/config/Jamfile.v2 +++ b/config/Jamfile.v2 @@ -8,12 +8,15 @@ import path ; local gmp_path = [ modules.peek : GMP_PATH ] ; local mpfr_path = [ modules.peek : MPFR_PATH ] ; +local tommath_path = [ modules.peek : TOMMATH_PATH ] ; obj has_gmp : has_gmp.cpp : $(gmp_path) $(gmp_path)/mpfr $(gmp_path)/gmpfrxx ; obj has_mpfr : has_mpfr.cpp : $(mpfr_path) $(gmp_path)/mpfr $(gmp_path)/gmpfrxx $(gmp_path) ; +obj has_tommath : has_tommath.cpp : + $(tommath_path) ; explicit has_gmp ; explicit has_mpfr ; - +explicit has_tommath ; diff --git a/config/has_e_float.cpp b/config/has_e_float.cpp deleted file mode 100644 index 8cadc5c6..00000000 --- a/config/has_e_float.cpp +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright John Maddock 2011. -// Use, modification and distribution are subject to the -// Boost Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - - -#ifdef _MSC_VER -# pragma warning (disable : 4100) // unreferenced formal parameter -#endif - -#define E_FLOAT_TYPE_EFX - -#include -#include -#include - - diff --git a/config/has_gcc_visibility.cpp b/config/has_gcc_visibility.cpp deleted file mode 100644 index 6c7d6f91..00000000 --- a/config/has_gcc_visibility.cpp +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright John Maddock 20010. -// Use, modification and distribution are subject to the -// Boost Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifndef __GNUC__ -# error "This is a GCC specific test case". -#endif - -int main() -{ - return 0; -} diff --git a/config/has_long_double_support.cpp b/config/has_long_double_support.cpp deleted file mode 100644 index d314cf38..00000000 --- a/config/has_long_double_support.cpp +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright John Maddock 2008. -// Use, modification and distribution are subject to the -// Boost Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#include - -#ifdef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS -#error "long double support is not supported by Boost.Math on this Plaform: the long double version of the TR1 library will not be built." -#endif diff --git a/config/has_mpfr_class.cpp b/config/has_mpfr_class.cpp deleted file mode 100644 index 8eb3c7b2..00000000 --- a/config/has_mpfr_class.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright John Maddock 2008. -// Copyright Paul A. Britow 2009 -// Use, modification and distribution are subject to the -// Boost Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifdef _MSC_VER -# pragma warning (disable : 4127) // conditional expression is constant -# pragma warning (disable : 4800) // 'int' : forcing value to bool 'true' or 'false' (performance warning) -# pragma warning (disable : 4512) // assignment operator could not be generated -#endif - -#include - diff --git a/config/has_mpreal.cpp b/config/has_mpreal.cpp deleted file mode 100644 index 8ee8897d..00000000 --- a/config/has_mpreal.cpp +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright John Maddock 2008. -// Copyright Paul A. Britow 2009 -// Use, modification and distribution are subject to the -// Boost Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - -#ifdef _MSC_VER -# pragma warning (disable : 4127) // conditional expression is constant -# pragma warning (disable : 4800) // 'int' : forcing value to bool 'true' or 'false' (performance warning) -# pragma warning (disable : 4512) // assignment operator could not be generated -#endif - -#include - diff --git a/config/has_ntl_rr.cpp b/config/has_ntl_rr.cpp deleted file mode 100644 index f3844217..00000000 --- a/config/has_ntl_rr.cpp +++ /dev/null @@ -1,12 +0,0 @@ -// Copyright John Maddock 2008. -// Use, modification and distribution are subject to the -// Boost Software License, Version 1.0. (See accompanying file -// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) - - -#ifdef _MSC_VER -# pragma warning (disable : 4100) // unreferenced formal parameter -#endif - -#include - diff --git a/config/has_gmpxx.cpp b/config/has_tommath.cpp similarity index 78% rename from config/has_gmpxx.cpp rename to config/has_tommath.cpp index edf62d8c..8d230043 100644 --- a/config/has_gmpxx.cpp +++ b/config/has_tommath.cpp @@ -1,7 +1,7 @@ -// Copyright John Maddock 2008. +// Copyright John Maddock 2011. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. (See accompanying file // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -#include +#include diff --git a/include/boost/multiprecision/arithmetic_backend.hpp b/include/boost/multiprecision/arithmetic_backend.hpp index 25f173ad..88098dab 100644 --- a/include/boost/multiprecision/arithmetic_backend.hpp +++ b/include/boost/multiprecision/arithmetic_backend.hpp @@ -119,7 +119,7 @@ inline void divide(arithmetic_backend& result, const arithmetic_back namespace std{ #ifdef BOOST_NO_NOEXCEPT -# define noexcept +# define BOOST_MP_NOEXCEPT #endif template @@ -128,19 +128,19 @@ class numeric_limits base_type; typedef boost::multiprecision::mp_number > 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(); } + BOOST_STATIC_CONSTEXPR number_type (min)() BOOST_MP_NOEXCEPT { return (base_type::min)(); } + BOOST_STATIC_CONSTEXPR number_type (max)() BOOST_MP_NOEXCEPT { return (base_type::max)(); } + BOOST_STATIC_CONSTEXPR number_type lowest() BOOST_MP_NOEXCEPT { return -(max)(); } + BOOST_STATIC_CONSTEXPR number_type epsilon() BOOST_MP_NOEXCEPT { return base_type::epsilon(); } + BOOST_STATIC_CONSTEXPR number_type round_error() BOOST_MP_NOEXCEPT { return epsilon() / 2; } + BOOST_STATIC_CONSTEXPR number_type infinity() BOOST_MP_NOEXCEPT { return base_type::infinity(); } + BOOST_STATIC_CONSTEXPR number_type quiet_NaN() BOOST_MP_NOEXCEPT { return base_type::quiet_NaN(); } + BOOST_STATIC_CONSTEXPR number_type signaling_NaN() BOOST_MP_NOEXCEPT { return base_type::signaling_NaN(); } + BOOST_STATIC_CONSTEXPR number_type denorm_min() BOOST_MP_NOEXCEPT { return base_type::denorm_min(); } }; #ifdef BOOST_NO_NOEXCEPT -# undef noexcept +# undef BOOST_MP_NOEXCEPT #endif } diff --git a/include/boost/multiprecision/concepts/mp_number_architypes.hpp b/include/boost/multiprecision/concepts/mp_number_architypes.hpp index a51f93b7..18a4b85c 100644 --- a/include/boost/multiprecision/concepts/mp_number_architypes.hpp +++ b/include/boost/multiprecision/concepts/mp_number_architypes.hpp @@ -194,7 +194,7 @@ typedef boost::multiprecision::mp_number mp_n namespace std{ #ifdef BOOST_NO_NOEXCEPT -# define noexcept +# define BOOST_MP_NOEXCEPT #endif template <> @@ -203,19 +203,19 @@ class numeric_limits typedef std::numeric_limits base_type; typedef boost::multiprecision::concepts::mp_number_float_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(); } + BOOST_STATIC_CONSTEXPR number_type (min)() BOOST_MP_NOEXCEPT { return (base_type::min)(); } + BOOST_STATIC_CONSTEXPR number_type (max)() BOOST_MP_NOEXCEPT { return (base_type::max)(); } + BOOST_STATIC_CONSTEXPR number_type lowest() BOOST_MP_NOEXCEPT { return -(max)(); } + BOOST_STATIC_CONSTEXPR number_type epsilon() BOOST_MP_NOEXCEPT { return base_type::epsilon(); } + BOOST_STATIC_CONSTEXPR number_type round_error() BOOST_MP_NOEXCEPT { return epsilon() / 2; } + BOOST_STATIC_CONSTEXPR number_type infinity() BOOST_MP_NOEXCEPT { return base_type::infinity(); } + BOOST_STATIC_CONSTEXPR number_type quiet_NaN() BOOST_MP_NOEXCEPT { return base_type::quiet_NaN(); } + BOOST_STATIC_CONSTEXPR number_type signaling_NaN() BOOST_MP_NOEXCEPT { return base_type::signaling_NaN(); } + BOOST_STATIC_CONSTEXPR number_type denorm_min() BOOST_MP_NOEXCEPT { return base_type::denorm_min(); } }; #ifdef BOOST_NO_NOEXCEPT -# undef noexcept +# undef BOOST_MP_NOEXCEPT #endif } diff --git a/include/boost/multiprecision/detail/mp_number_base.hpp b/include/boost/multiprecision/detail/mp_number_base.hpp index 6a7f0ff1..ca9cc5e9 100644 --- a/include/boost/multiprecision/detail/mp_number_base.hpp +++ b/include/boost/multiprecision/detail/mp_number_base.hpp @@ -10,6 +10,12 @@ #include #include +#ifdef BOOST_NO_NOEXCEPT +#define BOOST_MP_NOEXCEPT +#else +#define BOOST_MP_NOEXCEPT noexcept +#endif + namespace boost{ namespace multiprecision{ template diff --git a/include/boost/multiprecision/e_float.hpp b/include/boost/multiprecision/e_float.hpp deleted file mode 100644 index 68931334..00000000 --- a/include/boost/multiprecision/e_float.hpp +++ /dev/null @@ -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 -#include -#include -#include -#include - -namespace boost{ -namespace multiprecision{ - -typedef mp_number > e_float; - -template<> -inline void arithmetic_backend::negate() -{ - m_value.negate(); -} -template<> -inline std::string arithmetic_backend::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& result, const arithmetic_backend& arg) -{ - result.data() = ef::fabs(arg.data()); -} - -inline void eval_fabs(arithmetic_backend& result, const arithmetic_backend& arg) -{ - result.data() = ef::fabs(arg.data()); -} - -inline bool is_zero(const arithmetic_backend& val) -{ - return val.data().iszero(); -} -inline int get_sign(const arithmetic_backend& val) -{ - return val.data().isneg() ? -1 : val.data().iszero() ? 0 : 1; -} - -inline void convert_to(boost::uintmax_t* result, const arithmetic_backend& val) -{ - *result = val.data().extract_unsigned_long_long(); -} -inline void convert_to(boost::intmax_t* result, const arithmetic_backend& val) -{ - *result = val.data().extract_signed_long_long(); -} -inline void convert_to(double* result, const arithmetic_backend& val) -{ - *result = val.data().extract_double(); -} -inline void convert_to(long double* result, const arithmetic_backend& val) -{ - *result = val.data().extract_long_double(); -} -inline int eval_fpclassify(const arithmetic_backend& val) -{ - return val.data().isinf() ? FP_INFINITE : val.data().isnan() ? FP_NAN : val.data().iszero() ? FP_ZERO : FP_NORMAL; -} - - -}} // namespaces - -#endif diff --git a/include/boost/multiprecision/gmp.hpp b/include/boost/multiprecision/gmp.hpp index f5260057..80153bed 100644 --- a/include/boost/multiprecision/gmp.hpp +++ b/include/boost/multiprecision/gmp.hpp @@ -1656,7 +1656,7 @@ typedef mp_number mpq_rational; namespace std{ #ifdef BOOST_NO_NOEXCEPT -# define noexcept +# define BOOST_MP_NOEXCEPT #endif // @@ -1668,7 +1668,7 @@ class numeric_limits > number_type; public: BOOST_STATIC_CONSTEXPR bool is_specialized = true; - BOOST_STATIC_CONSTEXPR number_type (min)() noexcept + BOOST_STATIC_CONSTEXPR number_type (min)() BOOST_MP_NOEXCEPT { initializer.do_nothing(); static std::pair value; @@ -1680,7 +1680,7 @@ public: } return value.second; } - BOOST_STATIC_CONSTEXPR number_type (max)() noexcept + BOOST_STATIC_CONSTEXPR number_type (max)() BOOST_MP_NOEXCEPT { initializer.do_nothing(); static std::pair value; @@ -1692,7 +1692,7 @@ public: } return value.second; } - BOOST_STATIC_CONSTEXPR number_type lowest() noexcept + BOOST_STATIC_CONSTEXPR number_type lowest() BOOST_MP_NOEXCEPT { return -(max)(); } @@ -1704,7 +1704,7 @@ public: 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 + BOOST_STATIC_CONSTEXPR number_type epsilon() BOOST_MP_NOEXCEPT { initializer.do_nothing(); static std::pair value; @@ -1717,7 +1717,7 @@ public: return value.second; } // What value should this be???? - BOOST_STATIC_CONSTEXPR number_type round_error() noexcept + BOOST_STATIC_CONSTEXPR number_type round_error() BOOST_MP_NOEXCEPT { // returns epsilon/2 initializer.do_nothing(); @@ -1739,10 +1739,10 @@ public: 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(); } - BOOST_STATIC_CONSTEXPR number_type quiet_NaN() noexcept { return number_type(); } - BOOST_STATIC_CONSTEXPR number_type signaling_NaN() noexcept { return number_type(); } - BOOST_STATIC_CONSTEXPR number_type denorm_min() noexcept { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type infinity() BOOST_MP_NOEXCEPT { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type quiet_NaN() BOOST_MP_NOEXCEPT { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type signaling_NaN() BOOST_MP_NOEXCEPT { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type denorm_min() BOOST_MP_NOEXCEPT { return number_type(); } BOOST_STATIC_CONSTEXPR bool is_iec559 = false; BOOST_STATIC_CONSTEXPR bool is_bounded = true; BOOST_STATIC_CONSTEXPR bool is_modulo = false; @@ -1774,9 +1774,9 @@ class numeric_limits > number_type; public: BOOST_STATIC_CONSTEXPR bool is_specialized = false; - BOOST_STATIC_CONSTEXPR number_type (min)() noexcept { return number_type(); } - BOOST_STATIC_CONSTEXPR number_type (max)() noexcept { return number_type(); } - BOOST_STATIC_CONSTEXPR number_type lowest() noexcept { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type (min)() BOOST_MP_NOEXCEPT { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type (max)() BOOST_MP_NOEXCEPT { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type lowest() BOOST_MP_NOEXCEPT { return number_type(); } BOOST_STATIC_CONSTEXPR int digits = 0; BOOST_STATIC_CONSTEXPR int digits10 = 0; BOOST_STATIC_CONSTEXPR int max_digits10 = 0; @@ -1784,8 +1784,8 @@ public: 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(); } - BOOST_STATIC_CONSTEXPR number_type round_error() noexcept { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type epsilon() BOOST_MP_NOEXCEPT { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type round_error() BOOST_MP_NOEXCEPT { return number_type(); } BOOST_STATIC_CONSTEXPR int min_exponent = 0; BOOST_STATIC_CONSTEXPR int min_exponent10 = 0; BOOST_STATIC_CONSTEXPR int max_exponent = 0; @@ -1795,10 +1795,10 @@ public: 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(); } - BOOST_STATIC_CONSTEXPR number_type quiet_NaN() noexcept { return number_type(); } - BOOST_STATIC_CONSTEXPR number_type signaling_NaN() noexcept { return number_type(); } - BOOST_STATIC_CONSTEXPR number_type denorm_min() noexcept { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type infinity() BOOST_MP_NOEXCEPT { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type quiet_NaN() BOOST_MP_NOEXCEPT { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type signaling_NaN() BOOST_MP_NOEXCEPT { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type denorm_min() BOOST_MP_NOEXCEPT { return number_type(); } BOOST_STATIC_CONSTEXPR bool is_iec559 = false; BOOST_STATIC_CONSTEXPR bool is_bounded = false; BOOST_STATIC_CONSTEXPR bool is_modulo = false; @@ -1817,25 +1817,24 @@ public: // Largest and smallest numbers are bounded only by available memory, set // to zero: // - BOOST_STATIC_CONSTEXPR number_type (min)() noexcept + BOOST_STATIC_CONSTEXPR number_type (min)() BOOST_MP_NOEXCEPT { return number_type(); } - BOOST_STATIC_CONSTEXPR number_type (max)() noexcept + BOOST_STATIC_CONSTEXPR number_type (max)() BOOST_MP_NOEXCEPT { return number_type(); } - BOOST_STATIC_CONSTEXPR number_type lowest() noexcept { return (min)(); } - // Digits are unbounded, use zero for now: - BOOST_STATIC_CONSTEXPR int digits = 0; - BOOST_STATIC_CONSTEXPR int digits10 = 0; - BOOST_STATIC_CONSTEXPR int max_digits10 = 0; + BOOST_STATIC_CONSTEXPR number_type lowest() BOOST_MP_NOEXCEPT { return (min)(); } + BOOST_STATIC_CONSTEXPR int digits = INT_MAX; + BOOST_STATIC_CONSTEXPR int digits10 = (INT_MAX / 1000) * 301L; + BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 2; BOOST_STATIC_CONSTEXPR bool is_signed = true; BOOST_STATIC_CONSTEXPR bool is_integer = true; BOOST_STATIC_CONSTEXPR bool is_exact = true; BOOST_STATIC_CONSTEXPR int radix = 2; - BOOST_STATIC_CONSTEXPR number_type epsilon() noexcept { return number_type(); } - BOOST_STATIC_CONSTEXPR number_type round_error() noexcept { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type epsilon() BOOST_MP_NOEXCEPT { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type round_error() BOOST_MP_NOEXCEPT { return number_type(); } BOOST_STATIC_CONSTEXPR int min_exponent = 0; BOOST_STATIC_CONSTEXPR int min_exponent10 = 0; BOOST_STATIC_CONSTEXPR int max_exponent = 0; @@ -1845,10 +1844,10 @@ public: 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(); } - BOOST_STATIC_CONSTEXPR number_type quiet_NaN() noexcept { return number_type(); } - BOOST_STATIC_CONSTEXPR number_type signaling_NaN() noexcept { return number_type(); } - BOOST_STATIC_CONSTEXPR number_type denorm_min() noexcept { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type infinity() BOOST_MP_NOEXCEPT { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type quiet_NaN() BOOST_MP_NOEXCEPT { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type signaling_NaN() BOOST_MP_NOEXCEPT { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type denorm_min() BOOST_MP_NOEXCEPT { return number_type(); } BOOST_STATIC_CONSTEXPR bool is_iec559 = false; BOOST_STATIC_CONSTEXPR bool is_bounded = false; BOOST_STATIC_CONSTEXPR bool is_modulo = false; @@ -1867,15 +1866,15 @@ public: // Largest and smallest numbers are bounded only by available memory, set // to zero: // - BOOST_STATIC_CONSTEXPR number_type (min)() noexcept + BOOST_STATIC_CONSTEXPR number_type (min)() BOOST_MP_NOEXCEPT { return number_type(); } - BOOST_STATIC_CONSTEXPR number_type (max)() noexcept + BOOST_STATIC_CONSTEXPR number_type (max)() BOOST_MP_NOEXCEPT { return number_type(); } - BOOST_STATIC_CONSTEXPR number_type lowest() noexcept { return (min)(); } + BOOST_STATIC_CONSTEXPR number_type lowest() BOOST_MP_NOEXCEPT { return (min)(); } // Digits are unbounded, use zero for now: BOOST_STATIC_CONSTEXPR int digits = 0; BOOST_STATIC_CONSTEXPR int digits10 = 0; @@ -1884,8 +1883,8 @@ public: BOOST_STATIC_CONSTEXPR bool is_integer = false; BOOST_STATIC_CONSTEXPR bool is_exact = true; BOOST_STATIC_CONSTEXPR int radix = 2; - BOOST_STATIC_CONSTEXPR number_type epsilon() noexcept { return number_type(); } - BOOST_STATIC_CONSTEXPR number_type round_error() noexcept { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type epsilon() BOOST_MP_NOEXCEPT { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type round_error() BOOST_MP_NOEXCEPT { return number_type(); } BOOST_STATIC_CONSTEXPR int min_exponent = 0; BOOST_STATIC_CONSTEXPR int min_exponent10 = 0; BOOST_STATIC_CONSTEXPR int max_exponent = 0; @@ -1895,10 +1894,10 @@ public: 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(); } - BOOST_STATIC_CONSTEXPR number_type quiet_NaN() noexcept { return number_type(); } - BOOST_STATIC_CONSTEXPR number_type signaling_NaN() noexcept { return number_type(); } - BOOST_STATIC_CONSTEXPR number_type denorm_min() noexcept { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type infinity() BOOST_MP_NOEXCEPT { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type quiet_NaN() BOOST_MP_NOEXCEPT { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type signaling_NaN() BOOST_MP_NOEXCEPT { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type denorm_min() BOOST_MP_NOEXCEPT { return number_type(); } BOOST_STATIC_CONSTEXPR bool is_iec559 = false; BOOST_STATIC_CONSTEXPR bool is_bounded = false; BOOST_STATIC_CONSTEXPR bool is_modulo = false; @@ -1908,7 +1907,7 @@ public: }; #ifdef BOOST_NO_NOEXCEPT -# undef noexcept +# undef BOOST_MP_NOEXCEPT #endif } // namespace std diff --git a/include/boost/multiprecision/mpfr.hpp b/include/boost/multiprecision/mpfr.hpp index e37e5082..08ef8a92 100644 --- a/include/boost/multiprecision/mpfr.hpp +++ b/include/boost/multiprecision/mpfr.hpp @@ -967,7 +967,7 @@ struct lanczos > number_type; public: BOOST_STATIC_CONSTEXPR bool is_specialized = true; - BOOST_STATIC_CONSTEXPR number_type (min)() noexcept + BOOST_STATIC_CONSTEXPR number_type (min)() BOOST_MP_NOEXCEPT { initializer.do_nothing(); static std::pair value; @@ -991,7 +991,7 @@ public: } return value.second; } - BOOST_STATIC_CONSTEXPR number_type (max)() noexcept + BOOST_STATIC_CONSTEXPR number_type (max)() BOOST_MP_NOEXCEPT { initializer.do_nothing(); static std::pair value; @@ -1003,7 +1003,7 @@ public: } return value.second; } - BOOST_STATIC_CONSTEXPR number_type lowest() noexcept + BOOST_STATIC_CONSTEXPR number_type lowest() BOOST_MP_NOEXCEPT { return -(max)(); } @@ -1015,7 +1015,7 @@ public: 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 + BOOST_STATIC_CONSTEXPR number_type epsilon() BOOST_MP_NOEXCEPT { initializer.do_nothing(); static std::pair value; @@ -1028,7 +1028,7 @@ public: return value.second; } // What value should this be???? - BOOST_STATIC_CONSTEXPR number_type round_error() noexcept + BOOST_STATIC_CONSTEXPR number_type round_error() BOOST_MP_NOEXCEPT { // returns epsilon/2 initializer.do_nothing(); @@ -1050,7 +1050,7 @@ public: 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 + BOOST_STATIC_CONSTEXPR number_type infinity() BOOST_MP_NOEXCEPT { // returns epsilon/2 initializer.do_nothing(); @@ -1063,7 +1063,7 @@ public: } return value.second; } - BOOST_STATIC_CONSTEXPR number_type quiet_NaN() noexcept + BOOST_STATIC_CONSTEXPR number_type quiet_NaN() BOOST_MP_NOEXCEPT { // returns epsilon/2 initializer.do_nothing(); @@ -1076,11 +1076,11 @@ public: } return value.second; } - BOOST_STATIC_CONSTEXPR number_type signaling_NaN() noexcept + BOOST_STATIC_CONSTEXPR number_type signaling_NaN() BOOST_MP_NOEXCEPT { return number_type(0); } - BOOST_STATIC_CONSTEXPR number_type denorm_min() noexcept { return number_type(0); } + BOOST_STATIC_CONSTEXPR number_type denorm_min() BOOST_MP_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; @@ -1114,9 +1114,9 @@ class numeric_limits > 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 number_type (min)() BOOST_MP_NOEXCEPT { return number_type(0); } + BOOST_STATIC_CONSTEXPR number_type (max)() BOOST_MP_NOEXCEPT { return number_type(0); } + BOOST_STATIC_CONSTEXPR number_type lowest() BOOST_MP_NOEXCEPT { return number_type(0); } BOOST_STATIC_CONSTEXPR int digits = 0; BOOST_STATIC_CONSTEXPR int digits10 = 0; BOOST_STATIC_CONSTEXPR int max_digits10 = 0; @@ -1124,8 +1124,8 @@ public: 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 number_type epsilon() BOOST_MP_NOEXCEPT { return number_type(0); } + BOOST_STATIC_CONSTEXPR number_type round_error() BOOST_MP_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; @@ -1135,10 +1135,10 @@ public: 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 number_type infinity() BOOST_MP_NOEXCEPT { return number_type(0); } + BOOST_STATIC_CONSTEXPR number_type quiet_NaN() BOOST_MP_NOEXCEPT { return number_type(0); } + BOOST_STATIC_CONSTEXPR number_type signaling_NaN() BOOST_MP_NOEXCEPT { return number_type(0); } + BOOST_STATIC_CONSTEXPR number_type denorm_min() BOOST_MP_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; @@ -1147,8 +1147,8 @@ public: BOOST_STATIC_CONSTEXPR float_round_style round_style = round_toward_zero; }; -#ifdef noexcept -#undef noexcept +#ifdef BOOST_MP_NOEXCEPT +#undef BOOST_MP_NOEXCEPT #endif } // namespace std diff --git a/include/boost/multiprecision/tommath.hpp b/include/boost/multiprecision/tommath.hpp new file mode 100644 index 00000000..90448520 --- /dev/null +++ b/include/boost/multiprecision/tommath.hpp @@ -0,0 +1,411 @@ +/////////////////////////////////////////////////////////////////////////////// +// 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_MP_TOMMATH_BACKEND_HPP +#define BOOST_MATH_MP_TOMMATH_BACKEND_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost{ namespace multiprecision{ + +struct tommath_int +{ + typedef mpl::list signed_types; + typedef mpl::list unsigned_types; + typedef mpl::list float_types; + + tommath_int() + { + mp_init(&m_data); + } + tommath_int(const tommath_int& o) + { + mp_init_copy(&m_data, const_cast<::mp_int*>(&o.m_data)); + } + tommath_int& operator = (const tommath_int& o) + { + mp_copy(const_cast<::mp_int*>(&o.m_data), &m_data); + return *this; + } + tommath_int& operator = (boost::uintmax_t i) + { + boost::uintmax_t mask = ((1uLL << std::numeric_limits::digits) - 1); + unsigned shift = 0; + ::mp_int t; + mp_init(&t); + mp_zero(&m_data); + while(i) + { + mp_set_int(&t, static_cast(i & mask)); + if(shift) + mp_mul_2d(&t, shift, &t); + mp_add(&m_data, &t, &m_data); + shift += std::numeric_limits::digits; + i >>= std::numeric_limits::digits; + } + mp_clear(&t); + return *this; + } + tommath_int& operator = (boost::intmax_t i) + { + bool neg = i < 0; + *this = static_cast(std::abs(i)); + if(neg) + mp_neg(&m_data, &m_data); + return *this; + } + tommath_int& operator = (unsigned long i) + { + mp_set_int(&m_data, i); + return *this; + } + tommath_int& operator = (long i) + { + bool neg = i < 0; + *this = static_cast(std::abs(i)); + if(neg) + mp_neg(&m_data, &m_data); + return *this; + } + tommath_int& operator = (long double a) + { + using std::frexp; + using std::ldexp; + using std::floor; + + if (a == 0) { + mp_set_int(&m_data, 0); + return *this; + } + + if (a == 1) { + mp_set_int(&m_data, 1); + return *this; + } + + BOOST_ASSERT(!(boost::math::isinf)(a)); + BOOST_ASSERT(!(boost::math::isnan)(a)); + + int e; + long double f, term; + mp_init_set_int(&m_data, 0u); + ::mp_int t; + mp_init(&t); + + f = frexp(a, &e); + + static const int shift = std::numeric_limits::digits - 1; + + while(f) + { + // extract int sized bits from f: + f = ldexp(f, shift); + term = floor(f); + e -= shift; + mp_mul_2d(&m_data, shift, &m_data); + if(term > 0) + { + mp_set_int(&t, static_cast(term)); + mp_add(&m_data, &t, &m_data); + } + else + { + mp_set_int(&t, static_cast(-term)); + mp_sub(&m_data, &t, &m_data); + } + f -= term; + } + if(e > 0) + mp_mul_2d(&m_data, e, &m_data); + else if(e < 0) + { + tommath_int t2; + mp_div_2d(&m_data, -e, &m_data, &t2.data()); + } + return *this; + } + tommath_int& operator = (const char* s) + { + mp_read_radix(&m_data, s, 10); + return *this; + } + std::string str(unsigned /*digits*/, bool /*scientific*/)const + { + int s; + mp_radix_size(const_cast<::mp_int*>(&m_data), 10, &s); + boost::scoped_array a(new char[s+1]); + mp_toradix_n(const_cast<::mp_int*>(&m_data), a.get(), 10, s+1); + return a.get(); + } + ~tommath_int() + { + mp_clear(&m_data); + } + void negate() + { + mp_neg(&m_data, &m_data); + } + int compare(const tommath_int& o)const + { + return mp_cmp(const_cast<::mp_int*>(&m_data), const_cast<::mp_int*>(&o.m_data)); + } + template + int compare(V v)const + { + tommath_int d; + tommath_int t(*this); + mp_shrink(&t.data()); + d = v; + return t.compare(d); + } + mp_int& data() { return m_data; } + const mp_int& data()const { return m_data; } + void swap(tommath_int& o) + { + mp_exch(&m_data, &o.data()); + } +protected: + mp_int m_data; +}; + +int get_sign(const tommath_int& val); + +inline void add(tommath_int& t, const tommath_int& o) +{ + mp_add(&t.data(), const_cast<::mp_int*>(&o.data()), &t.data()); +} +inline void subtract(tommath_int& t, const tommath_int& o) +{ + mp_sub(&t.data(), const_cast<::mp_int*>(&o.data()), &t.data()); +} +inline void multiply(tommath_int& t, const tommath_int& o) +{ + mp_mul(&t.data(), const_cast<::mp_int*>(&o.data()), &t.data()); +} +inline void divide(tommath_int& t, const tommath_int& o) +{ + tommath_int temp; + mp_div(&t.data(), const_cast<::mp_int*>(&o.data()), &t.data(), &temp.data()); +} +inline void modulus(tommath_int& t, const tommath_int& o) +{ + bool neg = get_sign(t) < 0; + bool neg2 = get_sign(o) < 0; + mp_mod(&t.data(), const_cast<::mp_int*>(&o.data()), &t.data()); + if(neg != neg2) + { + t.negate(); + mp_add(&t.data(), const_cast<::mp_int*>(&o.data()), &t.data()); + t.negate(); + } +} +template +inline void left_shift(tommath_int& t, UI i) +{ + mp_mul_2d(&t.data(), static_cast(i), &t.data()); +} +template +inline void right_shift(tommath_int& t, UI i) +{ + tommath_int d; + mp_div_2d(&t.data(), static_cast(i), &t.data(), &d.data()); +} +template +inline void left_shift(tommath_int& t, const tommath_int& v, UI i) +{ + mp_mul_2d(const_cast<::mp_int*>(&v.data()), static_cast(i), &t.data()); +} +template +inline void right_shift(tommath_int& t, const tommath_int& v, UI i) +{ + tommath_int d; + mp_div_2d(const_cast<::mp_int*>(&v.data()), static_cast(i), &t.data(), &d.data()); +} + +inline void bitwise_and(tommath_int& result, const tommath_int& v) +{ + mp_and(&result.data(), const_cast<::mp_int*>(&v.data()), &result.data()); +} + +inline void bitwise_or(tommath_int& result, const tommath_int& v) +{ + mp_or(&result.data(), const_cast<::mp_int*>(&v.data()), &result.data()); +} + +inline void bitwise_xor(tommath_int& result, const tommath_int& v) +{ + mp_xor(&result.data(), const_cast<::mp_int*>(&v.data()), &result.data()); +} + +inline void add(tommath_int& t, const tommath_int& p, const tommath_int& o) +{ + mp_add(const_cast<::mp_int*>(&p.data()), const_cast<::mp_int*>(&o.data()), &t.data()); +} +inline void subtract(tommath_int& t, const tommath_int& p, const tommath_int& o) +{ + mp_sub(const_cast<::mp_int*>(&p.data()), const_cast<::mp_int*>(&o.data()), &t.data()); +} +inline void multiply(tommath_int& t, const tommath_int& p, const tommath_int& o) +{ + mp_mul(const_cast<::mp_int*>(&p.data()), const_cast<::mp_int*>(&o.data()), &t.data()); +} +inline void divide(tommath_int& t, const tommath_int& p, const tommath_int& o) +{ + tommath_int d; + mp_div(const_cast<::mp_int*>(&p.data()), const_cast<::mp_int*>(&o.data()), &t.data(), &d.data()); +} +inline void modulus(tommath_int& t, const tommath_int& p, const tommath_int& o) +{ + bool neg = get_sign(p) < 0; + bool neg2 = get_sign(o) < 0; + mp_mod(const_cast<::mp_int*>(&p.data()), const_cast<::mp_int*>(&o.data()), &t.data()); + if(neg != neg2) + { + t.negate(); + mp_add(&t.data(), const_cast<::mp_int*>(&o.data()), &t.data()); + t.negate(); + } +} + +inline void bitwise_and(tommath_int& result, const tommath_int& u, const tommath_int& v) +{ + mp_and(const_cast<::mp_int*>(&u.data()), const_cast<::mp_int*>(&v.data()), &result.data()); +} + +inline void bitwise_or(tommath_int& result, const tommath_int& u, const tommath_int& v) +{ + mp_or(const_cast<::mp_int*>(&u.data()), const_cast<::mp_int*>(&v.data()), &result.data()); +} + +inline void bitwise_xor(tommath_int& result, const tommath_int& u, const tommath_int& v) +{ + mp_xor(const_cast<::mp_int*>(&u.data()), const_cast<::mp_int*>(&v.data()), &result.data()); +} + +inline void complement(tommath_int& result, const tommath_int& u) +{ + result = u; + for(int i = 0; i < result.data().used; ++i) + { + result.data().dp[i] = MP_MASK & ~(result.data().dp[i]); + } + // + // We now need to pad out the left of the value with 1's to round up to a whole number of + // CHAR_BIT * sizeof(mp_digit) units. Otherwise we'll end up with a very strange number of + // bits set! + // + unsigned shift = result.data().used * DIGIT_BIT; // How many bits we're actually using + // How many bits we actually need, reduced by one to account for a mythical sign bit: + unsigned padding = result.data().used * std::numeric_limits::digits - shift - 1; + while(padding >= std::numeric_limits::digits) + padding -= std::numeric_limits::digits; + + // Create a mask providing the extra bits we need and add to result: + tommath_int mask; + mask = static_cast((1u << padding) - 1); + left_shift(mask, shift); + add(result, mask); +} + +inline bool is_zero(const tommath_int& val) +{ + return mp_iszero(&val.data()); +} +inline int get_sign(const tommath_int& val) +{ + return mp_iszero(&val.data()) ? 0 : SIGN(&val.data()) ? -1 : 1; +} +template +inline void convert_to(A* result, const tommath_int& val) +{ + *result = boost::lexical_cast(val.str(0, false)); +} +inline void convert_to(char* result, const tommath_int& val) +{ + *result = static_cast(boost::lexical_cast(val.str(0, false))); +} +inline void convert_to(unsigned char* result, const tommath_int& val) +{ + *result = static_cast(boost::lexical_cast(val.str(0, false))); +} +inline void convert_to(signed char* result, const tommath_int& val) +{ + *result = static_cast(boost::lexical_cast(val.str(0, false))); +} +inline void eval_abs(tommath_int& result, const tommath_int& val) +{ + mp_abs(const_cast<::mp_int*>(&val.data()), &result.data()); +} + + +template<> +struct number_category : public mpl::int_{}; + +typedef mp_number mp_int; + +}} // namespaces + +namespace std{ + +template<> +class numeric_limits +{ + typedef boost::multiprecision::mp_int number_type; +public: + BOOST_STATIC_CONSTEXPR bool is_specialized = true; + // + // Largest and smallest numbers are bounded only by available memory, set + // to zero: + // + BOOST_STATIC_CONSTEXPR number_type (min)() BOOST_MP_NOEXCEPT + { + return number_type(); + } + BOOST_STATIC_CONSTEXPR number_type (max)() BOOST_MP_NOEXCEPT + { + return number_type(); + } + BOOST_STATIC_CONSTEXPR number_type lowest() BOOST_MP_NOEXCEPT { return (min)(); } + BOOST_STATIC_CONSTEXPR int digits = INT_MAX; + BOOST_STATIC_CONSTEXPR int digits10 = (INT_MAX / 1000) * 301L; + BOOST_STATIC_CONSTEXPR int max_digits10 = digits10 + 2; + BOOST_STATIC_CONSTEXPR bool is_signed = true; + BOOST_STATIC_CONSTEXPR bool is_integer = true; + BOOST_STATIC_CONSTEXPR bool is_exact = true; + BOOST_STATIC_CONSTEXPR int radix = 2; + BOOST_STATIC_CONSTEXPR number_type epsilon() BOOST_MP_NOEXCEPT { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type round_error() BOOST_MP_NOEXCEPT { return number_type(); } + 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() BOOST_MP_NOEXCEPT { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type quiet_NaN() BOOST_MP_NOEXCEPT { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type signaling_NaN() BOOST_MP_NOEXCEPT { return number_type(); } + BOOST_STATIC_CONSTEXPR number_type denorm_min() BOOST_MP_NOEXCEPT { return number_type(); } + 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; +}; + +} + +#endif diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 3bd9ac01..a076a565 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -9,22 +9,35 @@ import path ; local ntl-path = [ modules.peek : NTL_PATH ] ; local gmp_path = [ modules.peek : GMP_PATH ] ; local mpfr_path = [ modules.peek : MPFR_PATH ] ; +local tommath_path = [ modules.peek : TOMMATH_PATH ] ; project : requirements $(gmp_path) $(gmp_path)/mpfr $(gmp_path)/gmpfrxx $(mpfr_path) + $(tommath_path) ../../.. $(gmp_path) $(mpfr_path) $(mpfr_path)/build.vc10/lib/Win32/Debug + $(tommath_path) msvc:static ; lib gmp ; lib mpfr ; +if $(tommath_path) +{ + TOMMATH = [ GLOB $(tommath_path) : *.c ] ; +} +else +{ + lib tommath ; + TOMMATH = tommath ; +} + run test_arithmetic.cpp : # command line : # input files @@ -87,6 +100,14 @@ run test_arithmetic.cpp mpfr gmp [ check-target-builds ../config//has_mpfr : : no ] : test_arithmetic_mpfr_50 ; +run test_arithmetic.cpp $(TOMMATH) + : # command line + : # input files + : # requirements + TEST_TOMMATH + [ check-target-builds ../config//has_tommath : : no ] + : test_arithmetic_tommath ; + run test_numeric_limits.cpp : # command line : # input files @@ -150,6 +171,14 @@ run test_numeric_limits.cpp [ check-target-builds ../config//has_mpfr : : no ] : test_numeric_limits_cpp_float ; +run test_numeric_limits.cpp $(TOMMATH) + : # command line + : # input files + : # requirements + TEST_TOMMATH + [ check-target-builds ../config//has_tommath : : no ] + : test_numeric_limits_tommath ; + run mp_number_concept_check.cpp mpfr : # command line : # input files diff --git a/test/test_arithmetic.cpp b/test/test_arithmetic.cpp index db49a85b..a39dc351 100644 --- a/test/test_arithmetic.cpp +++ b/test/test_arithmetic.cpp @@ -6,7 +6,7 @@ #include #include -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) && !defined(TEST_TOMMATH) # define TEST_MPF_50 # define TEST_MPF # define TEST_BACKEND @@ -15,6 +15,7 @@ # define TEST_MPFR_50 # define TEST_CPP_FLOAT # define TEST_MPQ +# define TEST_TOMMATH #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -37,6 +38,9 @@ #if defined(TEST_MPFR) || defined(TEST_MPFR_50) #include #endif +#ifdef TEST_TOMMATH +#include +#endif #define BOOST_TEST_THROW(x, EX)\ try { x; BOOST_ERROR("Expected exception not thrown"); } \ @@ -70,6 +74,14 @@ template bool isfloat(T){ return false; } << " tolerance = " << tol << std::endl;\ } +template +struct is_twos_complement_integer : public boost::mpl::true_ {}; + +#ifdef TEST_TOMMATH +template <> +struct is_twos_complement_integer : public boost::mpl::false_ {}; +#endif + template void test_integer_ops(const T&){} @@ -180,6 +192,7 @@ void test_integer_ops(const boost::mpl::int_::value ? ~0 : (std::numeric_limits::max)(); a = i; b = j; c = a; @@ -248,11 +261,11 @@ void test_integer_ops(const boost::mpl::int_(); +#endif +#ifdef TEST_TOMMATH + test(); #endif return boost::report_errors(); } diff --git a/test/test_numeric_limits.cpp b/test/test_numeric_limits.cpp index ce87c5d6..ea18665c 100644 --- a/test/test_numeric_limits.cpp +++ b/test/test_numeric_limits.cpp @@ -5,7 +5,7 @@ #include -#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) +#if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && !defined(TEST_CPP_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) && !defined(TEST_TOMMATH) # define TEST_MPF_50 # define TEST_MPF # define TEST_BACKEND @@ -14,6 +14,7 @@ # define TEST_MPFR_50 # define TEST_CPP_FLOAT # define TEST_MPQ +# define TEST_TOMMATH #ifdef _MSC_VER #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!") @@ -36,6 +37,9 @@ #if defined(TEST_MPFR) || defined(TEST_MPFR_50) #include #endif +#ifdef TEST_TOMMATH +#include +#endif #define PRINT(x)\ std::cout << BOOST_STRINGIZE(x) << " = " << std::numeric_limits::x << std::endl; @@ -168,6 +172,9 @@ int main() #endif #ifdef TEST_MPFR_50 test(); +#endif +#ifdef TEST_TOMMATH + test(); #endif return boost::report_errors(); }