|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r74042 - in sandbox/big_number: boost/math boost/math/big_number libs/math/test
From: john_at_[hidden]
Date: 2011-08-24 07:27:10
Author: johnmaddock
Date: 2011-08-24 07:27:08 EDT (Wed, 24 Aug 2011)
New Revision: 74042
URL: http://svn.boost.org/trac/boost/changeset/74042
Log:
Add sign and is_zero functions.
Add use in boolean context.
Text files modified:
sandbox/big_number/boost/math/big_number.hpp | 14 ++++++++
sandbox/big_number/boost/math/big_number/big_number_base.hpp | 65 ++++++++++++++++++++++++++++++---------
sandbox/big_number/boost/math/big_number/default_ops.hpp | 13 ++++++++
sandbox/big_number/boost/math/big_number/e_float.hpp | 11 ++++++
sandbox/big_number/boost/math/big_number/gmp.hpp | 20 ++++++++++++
sandbox/big_number/boost/math/big_number/mpfr.hpp | 11 ++++++
sandbox/big_number/libs/math/test/test_arithmetic.cpp | 49 ++++++++++++++++++++++++++++++
7 files changed, 166 insertions(+), 17 deletions(-)
Modified: sandbox/big_number/boost/math/big_number.hpp
==============================================================================
--- sandbox/big_number/boost/math/big_number.hpp (original)
+++ sandbox/big_number/boost/math/big_number.hpp 2011-08-24 07:27:08 EDT (Wed, 24 Aug 2011)
@@ -306,7 +306,19 @@
{
m_backend.swap(other.backend());
}
-
+ //
+ // Zero and sign:
+ //
+ bool is_zero()
+ {
+ using big_num_default_ops::is_zero;
+ return is_zero(m_backend);
+ }
+ int sign()
+ {
+ using big_num_default_ops::get_sign;
+ return get_sign(m_backend);
+ }
//
// String conversion functions:
//
Modified: sandbox/big_number/boost/math/big_number/big_number_base.hpp
==============================================================================
--- sandbox/big_number/boost/math/big_number/big_number_base.hpp (original)
+++ sandbox/big_number/boost/math/big_number/big_number_base.hpp 2011-08-24 07:27:08 EDT (Wed, 24 Aug 2011)
@@ -41,22 +41,6 @@
: proto::domain< proto::generator<big_number_exp>, big_number_grammar>
{};
-template<typename Expr>
-struct big_number_exp
- : proto::extends<Expr, big_number_exp<Expr>, big_number_domain>
-{
- typedef
- proto::extends<Expr, big_number_exp<Expr>, big_number_domain> base_type;
-
- big_number_exp(Expr const &expr = Expr())
- : base_type(expr)
- {}
- template <class Other>
- big_number_exp(const Other& o)
- : base_type(o)
- {}
-};
-
struct CalcDepth
: proto::or_<
proto::when< proto::terminal<proto::_>,
@@ -447,6 +431,55 @@
typedef Backend type;
};
+template<typename Expr>
+struct big_number_exp
+ : proto::extends<Expr, big_number_exp<Expr>, big_number_domain>
+{
+private:
+ typedef proto::extends<Expr, big_number_exp<Expr>, big_number_domain> base_type;
+ typedef big_number_exp<Expr> self_type;
+ typedef typename expression_type<self_type>::type number_type;
+ typedef void (self_type::*unmentionable_type)();
+ void unmentionable_proc(){}
+ unmentionable_type boolean_context_from_terminal(const number_type* pval)const
+ {
+ return pval->is_zero() ? 0 : &self_type::unmentionable_proc;
+ }
+ unmentionable_type boolean_context_from_terminal(number_type* pval)const
+ {
+ return pval->is_zero() ? 0 : &self_type::unmentionable_proc;
+ }
+ template <class Terminal>
+ unmentionable_type boolean_context_from_terminal(const Terminal& val)const
+ {
+ return val ? 0 : &self_type::unmentionable_proc;
+ }
+ unmentionable_type boolean_context(const proto::tag::terminal&)const
+ {
+ return boolean_context_from_terminal(proto::value(*this));
+ }
+ template <class Tag>
+ unmentionable_type boolean_context(const Tag&)const
+ {
+ // we have to evaluate the expression template:
+ number_type result(*this);
+ return result.is_zero() ? 0 : &self_type::unmentionable_proc;
+ }
+public:
+ big_number_exp(Expr const &expr = Expr())
+ : base_type(expr)
+ {}
+ template <class Other>
+ big_number_exp(const Other& o)
+ : base_type(o)
+ {}
+
+ operator unmentionable_type()const
+ {
+ return boolean_context(typename proto::tag_of<self_type>::type());
+ }
+};
+
} // namespace detail
//
Modified: sandbox/big_number/boost/math/big_number/default_ops.hpp
==============================================================================
--- sandbox/big_number/boost/math/big_number/default_ops.hpp (original)
+++ sandbox/big_number/boost/math/big_number/default_ops.hpp 2011-08-24 07:27:08 EDT (Wed, 24 Aug 2011)
@@ -174,6 +174,19 @@
right_shift(result, val);
}
+template <class T>
+inline bool is_zero(const T& val)
+{
+ typedef typename mpl::front<typename T::unsigned_types>::type ui_type;
+ return val.compare(static_cast<ui_type>(0)) == 0;
+}
+template <class T>
+inline int get_sign(const T& val)
+{
+ typedef typename mpl::front<typename T::unsigned_types>::type ui_type;
+ return val.compare(static_cast<ui_type>(0));
+}
+
//
// Functions:
//
Modified: sandbox/big_number/boost/math/big_number/e_float.hpp
==============================================================================
--- sandbox/big_number/boost/math/big_number/e_float.hpp (original)
+++ sandbox/big_number/boost/math/big_number/e_float.hpp 2011-08-24 07:27:08 EDT (Wed, 24 Aug 2011)
@@ -27,6 +27,17 @@
result->data() = ef::fabs(arg.data());
}
+inline bool is_zero(const arithmetic_backend<efx::e_float>& val)
+{
+ return val.data().iszero();
+}
+inline int get_sign(const arithmetic_backend<efx::e_float>& val)
+{
+ return val.data().isneg() ? -1 : val.data().iszero() ? 0 : 1;
+}
+
+
+
}} // namespaces
Modified: sandbox/big_number/boost/math/big_number/gmp.hpp
==============================================================================
--- sandbox/big_number/boost/math/big_number/gmp.hpp (original)
+++ sandbox/big_number/boost/math/big_number/gmp.hpp 2011-08-24 07:27:08 EDT (Wed, 24 Aug 2011)
@@ -542,6 +542,17 @@
mpf_ui_div(a.data(), x, y.data());
}
+template <unsigned digits10>
+inline bool is_zero(const gmp_real<digits10>& val)
+{
+ return mpf_sgn(val.data()) == 0;
+}
+template <unsigned digits10>
+inline int get_sign(const gmp_real<digits10>& val)
+{
+ return mpf_sgn(val.data());
+}
+
//
// Native non-member operations:
//
@@ -986,6 +997,15 @@
mpz_neg(t.data(), t.data());
}
+inline bool is_zero(const gmp_int& val)
+{
+ return mpz_sgn(val.data()) == 0;
+}
+inline int get_sign(const gmp_int& val)
+{
+ return mpz_sgn(val.data());
+}
+
inline void abs(gmp_int* result, const gmp_int& val)
{
mpz_abs(result->data(), val.data());
Modified: sandbox/big_number/boost/math/big_number/mpfr.hpp
==============================================================================
--- sandbox/big_number/boost/math/big_number/mpfr.hpp (original)
+++ sandbox/big_number/boost/math/big_number/mpfr.hpp 2011-08-24 07:27:08 EDT (Wed, 24 Aug 2011)
@@ -544,6 +544,17 @@
mpfr_ui_div(a.data(), x, y.data(), MPFR_RNDN);
}
+template <unsigned digits10>
+inline bool is_zero(const mpfr_real_backend<digits10>& val)
+{
+ return 0 != mpfr_zero_p(val.data());
+}
+template <unsigned digits10>
+inline int get_sign(const mpfr_real_backend<digits10>& val)
+{
+ return mpfr_sgn(val.data());
+}
+
//
// Native non-member operations:
//
Modified: sandbox/big_number/libs/math/test/test_arithmetic.cpp
==============================================================================
--- sandbox/big_number/libs/math/test/test_arithmetic.cpp (original)
+++ sandbox/big_number/libs/math/test/test_arithmetic.cpp 2011-08-24 07:27:08 EDT (Wed, 24 Aug 2011)
@@ -41,6 +41,16 @@
catch(const EX&){}\
catch(...){ BOOST_ERROR("Incorrect exception type thrown"); }
+#undef BOOST_TEST
+#define BOOST_TEST(x)\
+ try {\
+ if(x){}else{ BOOST_ERROR("Value was zero: "); }\
+ }\
+ catch(const std::exception& e){ \
+ BOOST_ERROR("Unexpected exception: ");\
+ BOOST_LIGHTWEIGHT_TEST_OSTREAM << e.what() << std::endl;\
+ }
+
template <class Real>
void test_integer_ops(const boost::mpl::false_&){}
@@ -631,6 +641,45 @@
BOOST_TEST((72 < b+a) == false);
BOOST_TEST((72 >= b+a) == true);
BOOST_TEST((72 > b+a) == false);
+ //
+ // Test sign and zero functions, plus use in boolian context:
+ //
+ a = 20;
+ BOOST_TEST(a.sign() > 0);
+ BOOST_TEST(!a.is_zero());
+ a = -20;
+ BOOST_TEST(a.sign() < 0);
+ BOOST_TEST(!a.is_zero());
+ a = 0;
+ BOOST_TEST(a.sign() == 0);
+ BOOST_TEST(a.is_zero());
+ if(a)
+ {
+ BOOST_ERROR("Unexpected non-zero result");
+ }
+ if(!a){}
+ else
+ {
+ BOOST_ERROR("Unexpected zero result");
+ }
+ b = 2;
+ if(!b)
+ {
+ BOOST_ERROR("Unexpected zero result");
+ }
+ if(b){}
+ else
+ {
+ BOOST_ERROR("Unexpected non-zero result");
+ }
+ if(a && b)
+ {
+ BOOST_ERROR("Unexpected zero result");
+ }
+ if(!(a || b))
+ {
+ BOOST_ERROR("Unexpected zero result");
+ }
}
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