Boost logo

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