Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r79823 - in sandbox/big_number: boost/multiprecision boost/multiprecision/detail libs/multiprecision/performance libs/multiprecision/test
From: john_at_[hidden]
Date: 2012-07-31 14:14:15


Author: johnmaddock
Date: 2012-07-31 14:14:14 EDT (Tue, 31 Jul 2012)
New Revision: 79823
URL: http://svn.boost.org/trac/boost/changeset/79823

Log:
Rework comparison operators - note that existing backends are made less efficient by this at present.
Added:
   sandbox/big_number/boost/multiprecision/detail/mp_number_compare.hpp (contents, props changed)
Text files modified:
   sandbox/big_number/boost/multiprecision/mp_number.hpp | 6
   sandbox/big_number/libs/multiprecision/performance/Jamfile.v2 | 4 +
   sandbox/big_number/libs/multiprecision/performance/arithmetic_backend.hpp | 149 ++++++++++++++++++++++++++++++++++++++-
   sandbox/big_number/libs/multiprecision/performance/sf_performance.cpp | 13 ++-
   sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp | 25 +++++
   5 files changed, 183 insertions(+), 14 deletions(-)

Added: sandbox/big_number/boost/multiprecision/detail/mp_number_compare.hpp
==============================================================================
--- (empty file)
+++ sandbox/big_number/boost/multiprecision/detail/mp_number_compare.hpp 2012-07-31 14:14:14 EDT (Tue, 31 Jul 2012)
@@ -0,0 +1,488 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright 2012 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_MP_COMPARE_HPP
+#define BOOST_MP_COMPARE_HPP
+
+//
+// Comparison operators for mp_number.
+//
+
+namespace boost{ namespace multiprecision{
+
+namespace default_ops{
+
+template <class B>
+inline bool eval_eq(const B& a, const B& b)
+{
+ return a.compare(b) == 0;
+}
+template <class B, class A>
+inline typename enable_if_c<(is_arithmetic<A>::value && is_convertible<A, B>::value), bool>::type eval_eq(const B& a, const A& b)
+{
+ B t(b);
+ return eval_eq(a, t);
+}
+template <class B, class A>
+inline typename enable_if_c<(is_arithmetic<A>::value && !is_convertible<A, B>::value), bool>::type eval_eq(const B& a, const A& b)
+{
+ B t;
+ t = b;
+ return eval_eq(a, t);
+}
+
+template <class B>
+inline bool eval_lt(const B& a, const B& b)
+{
+ return a.compare(b) < 0;
+}
+template <class B, class A>
+inline typename enable_if_c<(is_arithmetic<A>::value && is_convertible<A, B>::value), bool>::type eval_lt(const B& a, const A& b)
+{
+ B t(b);
+ return eval_lt(a, t);
+}
+template <class B, class A>
+inline typename enable_if_c<(is_arithmetic<A>::value && !is_convertible<A, B>::value), bool>::type eval_lt(const B& a, const A& b)
+{
+ B t;
+ t = b;
+ return eval_lt(a, t);
+}
+
+template <class B>
+inline bool eval_gt(const B& a, const B& b)
+{
+ return a.compare(b) > 0;
+}
+template <class B, class A>
+inline typename enable_if_c<(is_arithmetic<A>::value && is_convertible<A, B>::value), bool>::type eval_gt(const B& a, const A& b)
+{
+ B t(b);
+ return eval_gt(a, t);
+}
+template <class B, class A>
+inline typename enable_if_c<(is_arithmetic<A>::value && !is_convertible<A, B>::value), bool>::type eval_gt(const B& a, const A& b)
+{
+ B t;
+ t = b;
+ return eval_gt(a, t);
+}
+
+}
+
+template <class Backend, bool ExpressionTemplates>
+inline bool operator == (const mp_number<Backend, ExpressionTemplates>& a, const mp_number<Backend, ExpressionTemplates>& b)
+{
+ using default_ops::eval_eq;
+ return eval_eq(a.backend(), b.backend());
+}
+template <class Backend, bool ExpressionTemplates, class Arithmetic>
+inline typename enable_if_c<(is_convertible<Arithmetic, mp_number<Backend, ExpressionTemplates> >::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator == (const mp_number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
+{
+ typedef typename detail::canonical<Arithmetic, Backend>::type ct;
+ using default_ops::eval_eq;
+ return eval_eq(a.backend(), ct(b));
+}
+template <class Backend, bool ExpressionTemplates, class Tag, class A1, class A2, class A3, class A4>
+inline typename enable_if<is_same<mp_number<Backend, ExpressionTemplates>, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>, bool>::type
+ operator == (const mp_number<Backend, ExpressionTemplates>& a, const detail::mp_exp<Tag, A1, A2, A3, A4>& b)
+{
+ using default_ops::eval_eq;
+ typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type t(b);
+ return eval_eq(a.backend(), t.backend());
+}
+template <class Arithmetic, class Backend, bool ExpressionTemplates>
+inline typename enable_if_c<(is_convertible<Arithmetic, mp_number<Backend, ExpressionTemplates> >::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator == (const Arithmetic& a, const mp_number<Backend, ExpressionTemplates>& b)
+{
+ typedef typename detail::canonical<Arithmetic, Backend>::type ct;
+ using default_ops::eval_eq;
+ return eval_eq(b.backend(), ct(a));
+}
+template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
+inline typename enable_if_c<(is_convertible<Arithmetic, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator == (const Arithmetic& a, const detail::mp_exp<Tag, A1, A2, A3, A4>& b)
+{
+ typedef typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type result_type;
+ typedef typename detail::canonical<Arithmetic, typename result_type::backend_type>::type ct;
+ using default_ops::eval_eq;
+ result_type t(b);
+ return eval_eq(t.backend(), ct(a));
+}
+template <class Tag, class A1, class A2, class A3, class A4, class Backend, bool ExpressionTemplates>
+inline typename enable_if<is_same<mp_number<Backend, ExpressionTemplates>, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>, bool>::type
+ operator == (const detail::mp_exp<Tag, A1, A2, A3, A4>& a, const mp_number<Backend, ExpressionTemplates>& b)
+{
+ using default_ops::eval_eq;
+ typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type t(a);
+ return eval_eq(t.backend(), b.backend());
+}
+template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
+inline typename enable_if_c<(is_convertible<Arithmetic, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator == (const detail::mp_exp<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
+{
+ typedef typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type result_type;
+ typedef typename detail::canonical<Arithmetic, typename result_type::backend_type>::type ct;
+ using default_ops::eval_eq;
+ result_type t(a);
+ return eval_eq(t.backend(), ct(b));
+}
+template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
+inline typename enable_if<is_same<typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type, typename detail::mp_exp<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
+ operator == (const detail::mp_exp<Tag, A1, A2, A3, A4>& a, const detail::mp_exp<Tagb, A1b, A2b, A3b, A4b>& b)
+{
+ using default_ops::eval_eq;
+ typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type t(a);
+ typename detail::mp_exp<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
+ return eval_eq(t.backend(), t2.backend());
+}
+
+template <class Backend, bool ExpressionTemplates>
+inline bool operator != (const mp_number<Backend, ExpressionTemplates>& a, const mp_number<Backend, ExpressionTemplates>& b)
+{
+ using default_ops::eval_eq;
+ return !eval_eq(a.backend(), b.backend());
+}
+template <class Backend, bool ExpressionTemplates, class Arithmetic>
+inline typename enable_if_c<(is_convertible<Arithmetic, mp_number<Backend, ExpressionTemplates> >::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator != (const mp_number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
+{
+ typedef typename detail::canonical<Arithmetic, Backend>::type ct;
+ using default_ops::eval_eq;
+ return !eval_eq(a.backend(), ct(b));
+}
+template <class Backend, bool ExpressionTemplates, class Tag, class A1, class A2, class A3, class A4>
+inline typename enable_if<is_same<mp_number<Backend, ExpressionTemplates>, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>, bool>::type
+ operator != (const mp_number<Backend, ExpressionTemplates>& a, const detail::mp_exp<Tag, A1, A2, A3, A4>& b)
+{
+ using default_ops::eval_eq;
+ typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type t(b);
+ return !eval_eq(a.backend(), t.backend());
+}
+template <class Arithmetic, class Backend, bool ExpressionTemplates>
+inline typename enable_if_c<(is_convertible<Arithmetic, mp_number<Backend, ExpressionTemplates> >::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator != (const Arithmetic& a, const mp_number<Backend, ExpressionTemplates>& b)
+{
+ typedef typename detail::canonical<Arithmetic, Backend>::type ct;
+ using default_ops::eval_eq;
+ return !eval_eq(b.backend(), ct(a));
+}
+template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
+inline typename enable_if_c<(is_convertible<Arithmetic, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator != (const Arithmetic& a, const detail::mp_exp<Tag, A1, A2, A3, A4>& b)
+{
+ typedef typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type result_type;
+ typedef typename detail::canonical<Arithmetic, typename result_type::backend_type>::type ct;
+ using default_ops::eval_eq;
+ result_type t(b);
+ return !eval_eq(t.backend(), ct(a));
+}
+template <class Tag, class A1, class A2, class A3, class A4, class Backend, bool ExpressionTemplates>
+inline typename enable_if<is_same<mp_number<Backend, ExpressionTemplates>, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>, bool>::type
+ operator != (const detail::mp_exp<Tag, A1, A2, A3, A4>& a, const mp_number<Backend, ExpressionTemplates>& b)
+{
+ using default_ops::eval_eq;
+ typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type t(a);
+ return !eval_eq(t.backend(), b.backend());
+}
+template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
+inline typename enable_if_c<(is_convertible<Arithmetic, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator != (const detail::mp_exp<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
+{
+ typedef typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type result_type;
+ typedef typename detail::canonical<Arithmetic, typename result_type::backend_type>::type ct;
+ using default_ops::eval_eq;
+ result_type t(a);
+ return !eval_eq(t.backend(), ct(b));
+}
+template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
+inline typename enable_if<is_same<typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type, typename detail::mp_exp<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
+ operator != (const detail::mp_exp<Tag, A1, A2, A3, A4>& a, const detail::mp_exp<Tagb, A1b, A2b, A3b, A4b>& b)
+{
+ using default_ops::eval_eq;
+ typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type t(a);
+ typename detail::mp_exp<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
+ return !eval_eq(t.backend(), t2.backend());
+}
+
+template <class Backend, bool ExpressionTemplates>
+inline bool operator < (const mp_number<Backend, ExpressionTemplates>& a, const mp_number<Backend, ExpressionTemplates>& b)
+{
+ using default_ops::eval_lt;
+ return eval_lt(a.backend(), b.backend());
+}
+template <class Backend, bool ExpressionTemplates, class Arithmetic>
+inline typename enable_if_c<(is_convertible<Arithmetic, mp_number<Backend, ExpressionTemplates> >::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator < (const mp_number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
+{
+ typedef typename detail::canonical<Arithmetic, Backend>::type ct;
+ using default_ops::eval_lt;
+ return eval_lt(a.backend(), ct(b));
+}
+template <class Backend, bool ExpressionTemplates, class Tag, class A1, class A2, class A3, class A4>
+inline typename enable_if<is_same<mp_number<Backend, ExpressionTemplates>, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>, bool>::type
+ operator < (const mp_number<Backend, ExpressionTemplates>& a, const detail::mp_exp<Tag, A1, A2, A3, A4>& b)
+{
+ using default_ops::eval_lt;
+ typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type t(b);
+ return eval_lt(a.backend(), t.backend());
+}
+template <class Arithmetic, class Backend, bool ExpressionTemplates>
+inline typename enable_if_c<(is_convertible<Arithmetic, mp_number<Backend, ExpressionTemplates> >::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator < (const Arithmetic& a, const mp_number<Backend, ExpressionTemplates>& b)
+{
+ typedef typename detail::canonical<Arithmetic, Backend>::type ct;
+ using default_ops::eval_gt;
+ return eval_gt(b.backend(), ct(a));
+}
+template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
+inline typename enable_if_c<(is_convertible<Arithmetic, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator < (const Arithmetic& a, const detail::mp_exp<Tag, A1, A2, A3, A4>& b)
+{
+ typedef typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type result_type;
+ typedef typename detail::canonical<Arithmetic, typename result_type::backend_type>::type ct;
+ using default_ops::eval_gt;
+ result_type t(b);
+ return eval_gt(t.backend(), ct(a));
+}
+template <class Tag, class A1, class A2, class A3, class A4, class Backend, bool ExpressionTemplates>
+inline typename enable_if<is_same<mp_number<Backend, ExpressionTemplates>, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>, bool>::type
+ operator < (const detail::mp_exp<Tag, A1, A2, A3, A4>& a, const mp_number<Backend, ExpressionTemplates>& b)
+{
+ using default_ops::eval_lt;
+ typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type t(a);
+ return eval_lt(t.backend(), b.backend());
+}
+template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
+inline typename enable_if_c<(is_convertible<Arithmetic, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator < (const detail::mp_exp<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
+{
+ typedef typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type result_type;
+ typedef typename detail::canonical<Arithmetic, typename result_type::backend_type>::type ct;
+ using default_ops::eval_lt;
+ result_type t(a);
+ return eval_lt(t.backend(), ct(b));
+}
+template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
+inline typename enable_if<is_same<typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type, typename detail::mp_exp<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
+ operator < (const detail::mp_exp<Tag, A1, A2, A3, A4>& a, const detail::mp_exp<Tagb, A1b, A2b, A3b, A4b>& b)
+{
+ using default_ops::eval_lt;
+ typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type t(a);
+ typename detail::mp_exp<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
+ return eval_lt(t.backend(), t2.backend());
+}
+
+template <class Backend, bool ExpressionTemplates>
+inline bool operator > (const mp_number<Backend, ExpressionTemplates>& a, const mp_number<Backend, ExpressionTemplates>& b)
+{
+ using default_ops::eval_gt;
+ return eval_gt(a.backend(), b.backend());
+}
+template <class Backend, bool ExpressionTemplates, class Arithmetic>
+inline typename enable_if_c<(is_convertible<Arithmetic, mp_number<Backend, ExpressionTemplates> >::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator > (const mp_number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
+{
+ typedef typename detail::canonical<Arithmetic, Backend>::type ct;
+ using default_ops::eval_gt;
+ return eval_gt(a.backend(), ct(b));
+}
+template <class Backend, bool ExpressionTemplates, class Tag, class A1, class A2, class A3, class A4>
+inline typename enable_if<is_same<mp_number<Backend, ExpressionTemplates>, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>, bool>::type
+ operator > (const mp_number<Backend, ExpressionTemplates>& a, const detail::mp_exp<Tag, A1, A2, A3, A4>& b)
+{
+ using default_ops::eval_gt;
+ typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type t(b);
+ return eval_gt(a.backend(), t.backend());
+}
+template <class Arithmetic, class Backend, bool ExpressionTemplates>
+inline typename enable_if_c<(is_convertible<Arithmetic, mp_number<Backend, ExpressionTemplates> >::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator > (const Arithmetic& a, const mp_number<Backend, ExpressionTemplates>& b)
+{
+ typedef typename detail::canonical<Arithmetic, Backend>::type ct;
+ using default_ops::eval_lt;
+ return eval_lt(b.backend(), ct(a));
+}
+template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
+inline typename enable_if_c<(is_convertible<Arithmetic, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator > (const Arithmetic& a, const detail::mp_exp<Tag, A1, A2, A3, A4>& b)
+{
+ typedef typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type result_type;
+ typedef typename detail::canonical<Arithmetic, typename result_type::backend_type>::type ct;
+ using default_ops::eval_lt;
+ result_type t(b);
+ return eval_lt(t.backend(), ct(a));
+}
+template <class Tag, class A1, class A2, class A3, class A4, class Backend, bool ExpressionTemplates>
+inline typename enable_if<is_same<mp_number<Backend, ExpressionTemplates>, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>, bool>::type
+ operator > (const detail::mp_exp<Tag, A1, A2, A3, A4>& a, const mp_number<Backend, ExpressionTemplates>& b)
+{
+ using default_ops::eval_gt;
+ typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type t(a);
+ return eval_gt(t.backend(), b.backend());
+}
+template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
+inline typename enable_if_c<(is_convertible<Arithmetic, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator > (const detail::mp_exp<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
+{
+ typedef typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type result_type;
+ typedef typename detail::canonical<Arithmetic, typename result_type::backend_type>::type ct;
+ using default_ops::eval_gt;
+ result_type t(a);
+ return eval_gt(t.backend(), ct(b));
+}
+template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
+inline typename enable_if<is_same<typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type, typename detail::mp_exp<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
+ operator > (const detail::mp_exp<Tag, A1, A2, A3, A4>& a, const detail::mp_exp<Tagb, A1b, A2b, A3b, A4b>& b)
+{
+ using default_ops::eval_gt;
+ typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type t(a);
+ typename detail::mp_exp<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
+ return eval_gt(t.backend(), t2.backend());
+}
+
+template <class Backend, bool ExpressionTemplates>
+inline bool operator <= (const mp_number<Backend, ExpressionTemplates>& a, const mp_number<Backend, ExpressionTemplates>& b)
+{
+ using default_ops::eval_gt;
+ return !eval_gt(a.backend(), b.backend());
+}
+template <class Backend, bool ExpressionTemplates, class Arithmetic>
+inline typename enable_if_c<(is_convertible<Arithmetic, mp_number<Backend, ExpressionTemplates> >::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator <= (const mp_number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
+{
+ typedef typename detail::canonical<Arithmetic, Backend>::type ct;
+ using default_ops::eval_gt;
+ return !eval_gt(a.backend(), ct(b));
+}
+template <class Backend, bool ExpressionTemplates, class Tag, class A1, class A2, class A3, class A4>
+inline typename enable_if<is_same<mp_number<Backend, ExpressionTemplates>, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>, bool>::type
+ operator <= (const mp_number<Backend, ExpressionTemplates>& a, const detail::mp_exp<Tag, A1, A2, A3, A4>& b)
+{
+ using default_ops::eval_gt;
+ typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type t(b);
+ return !eval_gt(a.backend(), t.backend());
+}
+template <class Arithmetic, class Backend, bool ExpressionTemplates>
+inline typename enable_if_c<(is_convertible<Arithmetic, mp_number<Backend, ExpressionTemplates> >::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator <= (const Arithmetic& a, const mp_number<Backend, ExpressionTemplates>& b)
+{
+ typedef typename detail::canonical<Arithmetic, Backend>::type ct;
+ using default_ops::eval_lt;
+ return !eval_lt(b.backend(), ct(a));
+}
+template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
+inline typename enable_if_c<(is_convertible<Arithmetic, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator <= (const Arithmetic& a, const detail::mp_exp<Tag, A1, A2, A3, A4>& b)
+{
+ typedef typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type result_type;
+ typedef typename detail::canonical<Arithmetic, typename result_type::backend_type>::type ct;
+ using default_ops::eval_lt;
+ result_type t(b);
+ return !eval_lt(t.backend(), ct(a));
+}
+template <class Tag, class A1, class A2, class A3, class A4, class Backend, bool ExpressionTemplates>
+inline typename enable_if<is_same<mp_number<Backend, ExpressionTemplates>, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>, bool>::type
+ operator <= (const detail::mp_exp<Tag, A1, A2, A3, A4>& a, const mp_number<Backend, ExpressionTemplates>& b)
+{
+ using default_ops::eval_gt;
+ typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type t(a);
+ return !eval_gt(t.backend(), b.backend());
+}
+template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
+inline typename enable_if_c<(is_convertible<Arithmetic, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator <= (const detail::mp_exp<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
+{
+ typedef typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type result_type;
+ typedef typename detail::canonical<Arithmetic, typename result_type::backend_type>::type ct;
+ using default_ops::eval_gt;
+ result_type t(a);
+ return !eval_gt(t.backend(), ct(b));
+}
+template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
+inline typename enable_if<is_same<typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type, typename detail::mp_exp<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
+ operator <= (const detail::mp_exp<Tag, A1, A2, A3, A4>& a, const detail::mp_exp<Tagb, A1b, A2b, A3b, A4b>& b)
+{
+ using default_ops::eval_gt;
+ typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type t(a);
+ typename detail::mp_exp<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
+ return !eval_gt(t.backend(), t2.backend());
+}
+
+template <class Backend, bool ExpressionTemplates>
+inline bool operator >= (const mp_number<Backend, ExpressionTemplates>& a, const mp_number<Backend, ExpressionTemplates>& b)
+{
+ using default_ops::eval_lt;
+ return !eval_lt(a.backend(), b.backend());
+}
+template <class Backend, bool ExpressionTemplates, class Arithmetic>
+inline typename enable_if_c<(is_convertible<Arithmetic, mp_number<Backend, ExpressionTemplates> >::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator >= (const mp_number<Backend, ExpressionTemplates>& a, const Arithmetic& b)
+{
+ typedef typename detail::canonical<Arithmetic, Backend>::type ct;
+ using default_ops::eval_lt;
+ return !eval_lt(a.backend(), ct(b));
+}
+template <class Backend, bool ExpressionTemplates, class Tag, class A1, class A2, class A3, class A4>
+inline typename enable_if<is_same<mp_number<Backend, ExpressionTemplates>, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>, bool>::type
+ operator >= (const mp_number<Backend, ExpressionTemplates>& a, const detail::mp_exp<Tag, A1, A2, A3, A4>& b)
+{
+ using default_ops::eval_lt;
+ typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type t(b);
+ return !eval_lt(a.backend(), t.backend());
+}
+template <class Arithmetic, class Backend, bool ExpressionTemplates>
+inline typename enable_if_c<(is_convertible<Arithmetic, mp_number<Backend, ExpressionTemplates> >::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator >= (const Arithmetic& a, const mp_number<Backend, ExpressionTemplates>& b)
+{
+ typedef typename detail::canonical<Arithmetic, Backend>::type ct;
+ using default_ops::eval_gt;
+ return !eval_gt(b.backend(), ct(a));
+}
+template <class Arithmetic, class Tag, class A1, class A2, class A3, class A4>
+inline typename enable_if_c<(is_convertible<Arithmetic, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator >= (const Arithmetic& a, const detail::mp_exp<Tag, A1, A2, A3, A4>& b)
+{
+ typedef typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type result_type;
+ typedef typename detail::canonical<Arithmetic, typename result_type::backend_type>::type ct;
+ using default_ops::eval_gt;
+ result_type t(b);
+ return !eval_gt(t.backend(), ct(a));
+}
+template <class Tag, class A1, class A2, class A3, class A4, class Backend, bool ExpressionTemplates>
+inline typename enable_if<is_same<mp_number<Backend, ExpressionTemplates>, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>, bool>::type
+ operator >= (const detail::mp_exp<Tag, A1, A2, A3, A4>& a, const mp_number<Backend, ExpressionTemplates>& b)
+{
+ using default_ops::eval_lt;
+ typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type t(a);
+ return !eval_lt(t.backend(), b.backend());
+}
+template <class Tag, class A1, class A2, class A3, class A4, class Arithmetic>
+inline typename enable_if_c<(is_convertible<Arithmetic, typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type>::value && !is_mp_number_expression<Arithmetic>::value && !is_mp_number<Arithmetic>::value), bool>::type
+ operator >= (const detail::mp_exp<Tag, A1, A2, A3, A4>& a, const Arithmetic& b)
+{
+ typedef typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type result_type;
+ typedef typename detail::canonical<Arithmetic, typename result_type::backend_type>::type ct;
+ using default_ops::eval_lt;
+ result_type t(a);
+ return !eval_lt(t.backend(), ct(b));
+}
+template <class Tag, class A1, class A2, class A3, class A4, class Tagb, class A1b, class A2b, class A3b, class A4b>
+inline typename enable_if<is_same<typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type, typename detail::mp_exp<Tagb, A1b, A2b, A3b, A4b>::result_type>, bool>::type
+ operator >= (const detail::mp_exp<Tag, A1, A2, A3, A4>& a, const detail::mp_exp<Tagb, A1b, A2b, A3b, A4b>& b)
+{
+ using default_ops::eval_lt;
+ typename detail::mp_exp<Tag, A1, A2, A3, A4>::result_type t(a);
+ typename detail::mp_exp<Tagb, A1b, A2b, A3b, A4b>::result_type t2(b);
+ return !eval_lt(t.backend(), t2.backend());
+}
+
+
+}} // namespaces
+
+#endif // BOOST_MP_COMPARE_HPP
+

Modified: sandbox/big_number/boost/multiprecision/mp_number.hpp
==============================================================================
--- sandbox/big_number/boost/multiprecision/mp_number.hpp (original)
+++ sandbox/big_number/boost/multiprecision/mp_number.hpp 2012-07-31 14:14:14 EDT (Tue, 31 Jul 2012)
@@ -20,6 +20,7 @@
 #include <boost/type_traits/make_unsigned.hpp>
 #include <boost/throw_exception.hpp>
 #include <boost/multiprecision/detail/generic_interconvert.hpp>
+#include <boost/multiprecision/detail/mp_number_compare.hpp>
 #include <istream> // stream operators
 #include <cstdio> // EOF
 
@@ -1630,14 +1631,13 @@
 
 }
 
-
+/*
 template <class Exp1, class Exp2>
 inline typename boost::enable_if<detail::is_valid_comparison<Exp1, Exp2>, bool>::type
    operator == (const Exp1& a, const Exp2& b)
 {
    return 0 == detail::mp_number_compare(a, b);
 }
-
 template <class Exp1, class Exp2>
 inline typename boost::enable_if<detail::is_valid_comparison<Exp1, Exp2>, bool>::type
    operator != (const Exp1& a, const Exp2& b)
@@ -1672,7 +1672,7 @@
 {
    return 0 < detail::mp_number_compare(a, b);
 }
-
+*/
 template <class Backend, bool ExpressionTemplates>
 inline std::ostream& operator << (std::ostream& os, const mp_number<Backend, ExpressionTemplates>& r)
 {

Modified: sandbox/big_number/libs/multiprecision/performance/Jamfile.v2
==============================================================================
--- sandbox/big_number/libs/multiprecision/performance/Jamfile.v2 (original)
+++ sandbox/big_number/libs/multiprecision/performance/Jamfile.v2 2012-07-31 14:14:14 EDT (Tue, 31 Jul 2012)
@@ -69,6 +69,8 @@
           <define>TEST_CPP_DEC_FLOAT
           <toolset>msvc:<cxxflags>-bigobj
           ;
+
+exe delaunay_test : delaunay_test.cpp /boost/system//boost_system /boost/chrono//boost_chrono ;
 
 obj obj_linpack_benchmark_mpfr : linpack-benchmark.cpp
           : release
@@ -118,4 +120,6 @@
 install performance_test_install : performance_test : <location>. ;
 install sf_performance_install : sf_performance : <location>. ;
 install . : linpack_benchmark_double linpack_benchmark_cpp_float linpack_benchmark_mpf linpack_benchmark_mpfr ;
+install delaunay_install : delaunay_test : <location>. ;
+
 

Modified: sandbox/big_number/libs/multiprecision/performance/arithmetic_backend.hpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/performance/arithmetic_backend.hpp (original)
+++ sandbox/big_number/libs/multiprecision/performance/arithmetic_backend.hpp 2012-07-31 14:14:14 EDT (Tue, 31 Jul 2012)
@@ -18,6 +18,11 @@
 namespace multiprecision{
 namespace backends{
 
+#ifdef BOOST_MSVC
+# pragma warning(push)
+# pragma warning(disable:4389 4244 4018 4244 4127)
+#endif
+
 template <class Arithmetic>
 struct arithmetic_backend
 {
@@ -46,7 +51,14 @@
    }
    arithmetic_backend& operator = (const char* s)
    {
- m_value = boost::lexical_cast<double>(s);
+ try
+ {
+ m_value = boost::lexical_cast<Arithmetic>(s);
+ }
+ catch(const bad_lexical_cast&)
+ {
+ throw std::runtime_error(std::string("Unable to interpret the string provided: \"") + s + std::string("\" as a compatible number type."));
+ }
       return *this;
    }
    void swap(arithmetic_backend& o)
@@ -57,13 +69,21 @@
    {
       std::stringstream ss;
       ss.flags(f);
- ss << std::setprecision(digits) << m_value;
+ ss << std::setprecision(digits ? digits : std::numeric_limits<Arithmetic>::digits10 + 4) << m_value;
       return ss.str();
    }
- void negate()
+ void do_negate(const mpl::true_&)
+ {
+ m_value = 1 + ~m_value;
+ }
+ void do_negate(const mpl::false_&)
    {
       m_value = -m_value;
    }
+ void negate()
+ {
+ do_negate(is_unsigned<Arithmetic>());
+ }
    int compare(const arithmetic_backend& o)const
    {
       return m_value > o.m_value ? 1 : (m_value < o.m_value ? -1 : 0);
@@ -86,6 +106,37 @@
 }
 
 template <class Arithmetic>
+inline bool eval_eq(const arithmetic_backend<Arithmetic>& a, const arithmetic_backend<Arithmetic>& b)
+{
+ return a.data() == b.data();
+}
+template <class Arithmetic, class A2>
+inline bool eval_eq(const arithmetic_backend<Arithmetic>& a, const A2& b)
+{
+ return a.data() == b;
+}
+template <class Arithmetic>
+inline bool eval_lt(const arithmetic_backend<Arithmetic>& a, const arithmetic_backend<Arithmetic>& b)
+{
+ return a.data() < b.data();
+}
+template <class Arithmetic, class A2>
+inline bool eval_lt(const arithmetic_backend<Arithmetic>& a, const A2& b)
+{
+ return a.data() < b;
+}
+template <class Arithmetic>
+inline bool eval_gt(const arithmetic_backend<Arithmetic>& a, const arithmetic_backend<Arithmetic>& b)
+{
+ return a.data() > b.data();
+}
+template <class Arithmetic, class A2>
+inline bool eval_gt(const arithmetic_backend<Arithmetic>& a, const A2& b)
+{
+ return a.data() > b;
+}
+
+template <class Arithmetic>
 inline void eval_add(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
 {
    result.data() += o.data();
@@ -103,6 +154,8 @@
 template <class Arithmetic>
 inline void eval_divide(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
 {
+ if(!std::numeric_limits<Arithmetic>::has_infinity && !o.data())
+ BOOST_THROW_EXCEPTION(std::runtime_error("Divide by zero"));
    result.data() /= o.data();
 }
 
@@ -124,6 +177,8 @@
 template <class Arithmetic, class A2>
 inline typename enable_if<is_arithmetic<A2> >::type eval_divide(arithmetic_backend<Arithmetic>& result, const A2& o)
 {
+ if(!std::numeric_limits<Arithmetic>::has_infinity && !o)
+ BOOST_THROW_EXCEPTION(std::runtime_error("Divide by zero"));
    result.data() /= o;
 }
 
@@ -145,6 +200,8 @@
 template <class Arithmetic>
 inline void eval_divide(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, const arithmetic_backend<Arithmetic>& b)
 {
+ if(!std::numeric_limits<Arithmetic>::has_infinity && !b.data())
+ BOOST_THROW_EXCEPTION(std::runtime_error("Divide by zero"));
    result.data() = a.data() / b.data();
 }
 
@@ -166,6 +223,8 @@
 template <class Arithmetic, class A2>
 inline typename enable_if<is_arithmetic<A2>>::type eval_divide(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, const A2& b)
 {
+ if(!std::numeric_limits<Arithmetic>::has_infinity && !b)
+ BOOST_THROW_EXCEPTION(std::runtime_error("Divide by zero"));
    result.data() = a.data() / b;
 }
 
@@ -181,10 +240,15 @@
    return val.data() == 0 ? 0 : val.data() < 0 ? -1 : 1;
 }
 
+template <class T>
+inline typename enable_if<is_unsigned<T>, T>::type abs(T v) { return v; }
+
 template <class Arithmetic>
 inline void eval_abs(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
 {
- result.data() = std::abs(o.data());
+ using std::abs;
+ using boost::multiprecision::backends::abs;
+ result.data() = abs(o.data());
 }
 
 template <class Arithmetic>
@@ -235,6 +299,20 @@
 }
 
 template <class Arithmetic>
+inline void eval_frexp(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, int* v)
+{
+ BOOST_MATH_STD_USING
+ result.data() = frexp(a.data(), v);
+}
+
+template <class Arithmetic>
+inline void eval_ldexp(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, int v)
+{
+ BOOST_MATH_STD_USING
+ result.data() = ldexp(a.data(), v);
+}
+
+template <class Arithmetic>
 inline void eval_exp(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& o)
 {
    BOOST_MATH_STD_USING
@@ -339,10 +417,71 @@
    result.data() = atan2(a.data(), b.data());
 }
 
+template <class Arithmetic, class I>
+inline void eval_left_shift(arithmetic_backend<Arithmetic>& result, I val)
+{
+ result.data() <<= val;
+}
+
+template <class Arithmetic, class I>
+inline void eval_right_shift(arithmetic_backend<Arithmetic>& result, I val)
+{
+ result.data() >>= val;
+}
+
+template <class Arithmetic>
+inline void eval_modulus(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a)
+{
+ result.data() %= a.data();
+}
+
+template <class Arithmetic>
+inline void eval_bitwise_and(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a)
+{
+ result.data() &= a.data();
+}
+
+template <class Arithmetic>
+inline void eval_bitwise_or(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a)
+{
+ result.data() |= a.data();
+}
+
+template <class Arithmetic>
+inline void eval_bitwise_xor(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a)
+{
+ result.data() ^= a.data();
+}
+
+template <class Arithmetic>
+inline void eval_complement(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a)
+{
+ result.data() = ~a.data();
+}
+
+template <class Arithmetic>
+inline void eval_gcd(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, const arithmetic_backend<Arithmetic>& b)
+{
+ result.data() = boost::math::gcd(a.data(), b.data());
+}
+
+template <class Arithmetic>
+inline void eval_lcm(arithmetic_backend<Arithmetic>& result, const arithmetic_backend<Arithmetic>& a, const arithmetic_backend<Arithmetic>& b)
+{
+ result.data() = boost::math::lcm(a.data(), b.data());
+}
+
+#ifdef BOOST_MSVC
+# pragma warning(pop)
+#endif
+
 } // namespace backends
 
 using boost::multiprecision::backends::arithmetic_backend;
 
+template <class Arithmetic>
+struct number_category<arithmetic_backend<Arithmetic> > : public mpl::int_<is_integral<Arithmetic>::value ? number_kind_integer : number_kind_floating_point>{};
+
 }} // namespaces
 
 namespace boost{ namespace math{ namespace tools{
@@ -394,4 +533,6 @@
 
 }
 
+#include <boost/multiprecision/integer_ops.hpp>
+
 #endif

Modified: sandbox/big_number/libs/multiprecision/performance/sf_performance.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/performance/sf_performance.cpp (original)
+++ sandbox/big_number/libs/multiprecision/performance/sf_performance.cpp 2012-07-31 14:14:14 EDT (Tue, 31 Jul 2012)
@@ -257,10 +257,15 @@
    // Comparison for builtin floats:
    //
 #ifdef TEST_FLOAT
- time_proc("double", test_bessel<double>);
- time_proc("real_concept", test_bessel<boost::math::concepts::real_concept>);
- time_proc("arithmetic_backend<double>", test_bessel<mp_number<arithmetic_backend<double> > >);
- time_proc("arithmetic_backend<double> - no expression templates", test_bessel<mp_number<arithmetic_backend<double>, false> >);
+ time_proc("Bessel Functions - double", test_bessel<double>);
+ time_proc("Bessel Functions - real_concept", test_bessel<boost::math::concepts::real_concept>);
+ time_proc("Bessel Functions - arithmetic_backend<double>", test_bessel<mp_number<arithmetic_backend<double> > >);
+ time_proc("Bessel Functions - arithmetic_backend<double> - no expression templates", test_bessel<mp_number<arithmetic_backend<double>, false> >);
+
+ time_proc("Non-central T - double", test_nct<double>);
+ time_proc("Non-central T - real_concept", test_nct<boost::math::concepts::real_concept>);
+ time_proc("Non-central T - arithmetic_backend<double>", test_nct<mp_number<arithmetic_backend<double> > >);
+ time_proc("Non-central T - arithmetic_backend<double> - no expression templates", test_nct<mp_number<arithmetic_backend<double>, false> >);
 #endif
 
    //

Modified: sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp
==============================================================================
--- sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp (original)
+++ sandbox/big_number/libs/multiprecision/test/test_arithmetic.cpp 2012-07-31 14:14:14 EDT (Tue, 31 Jul 2012)
@@ -18,7 +18,7 @@
 #if !defined(TEST_MPF_50) && !defined(TEST_MPF) && !defined(TEST_BACKEND) && !defined(TEST_MPZ) && \
    !defined(TEST_CPP_DEC_FLOAT) && !defined(TEST_MPFR) && !defined(TEST_MPFR_50) && !defined(TEST_MPQ) \
    && !defined(TEST_TOMMATH) && !defined(TEST_TOMMATH_BOOST_RATIONAL) && !defined(TEST_MPZ_BOOST_RATIONAL)\
- && !defined(TEST_CPP_INT) && !defined(TEST_CPP_INT_BR)
+ && !defined(TEST_CPP_INT) && !defined(TEST_CPP_INT_BR) && !defined(TEST_ARITHMETIC_BACKEND)
 # define TEST_MPF_50
 # define TEST_MPF
 # define TEST_BACKEND
@@ -30,6 +30,7 @@
 # define TEST_TOMMATH
 # define TEST_CPP_INT
 # define TEST_CPP_INT_BR
+# define TEST_ARITHMETIC_BACKEND
 
 #ifdef _MSC_VER
 #pragma message("CAUTION!!: No backend type specified so testing everything.... this will take some time!!")
@@ -40,6 +41,9 @@
 
 #endif
 
+#if defined(TEST_ARITHMETIC_BACKEND)
+# include "../performance/arithmetic_backend.hpp"
+#endif
 #if defined(TEST_MPF_50) || defined(TEST_MPF) || defined(TEST_MPZ) || defined(TEST_MPQ) || defined(TEST_MPZ_BOOST_RATIONAL)
 #include <boost/multiprecision/gmp.hpp>
 #include <boost/multiprecision/rational_adapter.hpp>
@@ -628,7 +632,10 @@
    Num tol = 0;
 #endif
    std::ios_base::fmtflags f = boost::is_floating_point<Num>::value ? std::ios_base::scientific : std::ios_base::fmtflags(0);
- BOOST_TEST_CLOSE(n1, boost::lexical_cast<target_type>(Real(n1).str(0, f)), tol);
+ if(std::numeric_limits<target_type>::digits <= std::numeric_limits<Real>::digits)
+ {
+ BOOST_TEST_CLOSE(n1, boost::lexical_cast<target_type>(Real(n1).str(0, f)), tol);
+ }
    BOOST_TEST_CLOSE(n2, boost::lexical_cast<target_type>(Real(n2).str(0, f)), 0);
    BOOST_TEST_CLOSE(n3, boost::lexical_cast<target_type>(Real(n3).str(0, f)), 0);
    BOOST_TEST_CLOSE(n4, boost::lexical_cast<target_type>(Real(n4).str(0, f)), 0);
@@ -693,6 +700,10 @@
 void test_mixed()
 {
    typedef typename lexical_cast_target_type<Num>::type target_type;
+
+ if(std::numeric_limits<Real>::digits < std::numeric_limits<Num>::digits)
+ return;
+
    std::cout << "Testing mixed arithmetic with type: " << typeid(Real).name() << " and " << typeid(Num).name() << std::endl;
    Num n1 = static_cast<Num>(1uLL << (std::numeric_limits<Num>::digits - 1));
    Num n2 = 1;
@@ -730,7 +741,10 @@
    Num tol = 0;
 #endif
    std::ios_base::fmtflags f = boost::is_floating_point<Num>::value ? std::ios_base::scientific : std::ios_base::fmtflags(0);
- BOOST_TEST_CLOSE(n1, boost::lexical_cast<target_type>(Real(n1).str(0, f)), tol);
+ if(std::numeric_limits<target_type>::digits <= std::numeric_limits<Real>::digits)
+ {
+ BOOST_TEST_CLOSE(n1, boost::lexical_cast<target_type>(Real(n1).str(0, f)), tol);
+ }
    BOOST_TEST_CLOSE(n2, boost::lexical_cast<target_type>(Real(n2).str(0, f)), 0);
    BOOST_TEST_CLOSE(n3, boost::lexical_cast<target_type>(Real(n3).str(0, f)), 0);
    BOOST_TEST_CLOSE(n4, boost::lexical_cast<target_type>(Real(n4).str(0, f)), 0);
@@ -1126,6 +1140,11 @@
 
 int main()
 {
+#ifdef TEST_ARITHMETIC_BACKEND
+ test<boost::multiprecision::mp_number<boost::multiprecision::arithmetic_backend<double> > >();
+ test<boost::multiprecision::mp_number<boost::multiprecision::arithmetic_backend<int> > >();
+ test<boost::multiprecision::mp_number<boost::multiprecision::arithmetic_backend<unsigned int> > >();
+#endif
 #ifdef TEST_BACKEND
    test<boost::multiprecision::mp_number<boost::multiprecision::concepts::mp_number_backend_float_architype> >();
 #endif


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk