Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r77181 - in sandbox/fixed_point: boost/fixed_point libs/fixed_point/example
From: vicente.botet_at_[hidden]
Date: 2012-03-03 13:54:56


Author: viboes
Date: 2012-03-03 13:54:56 EST (Sat, 03 Mar 2012)
New Revision: 77181
URL: http://svn.boost.org/trac/boost/changeset/77181

Log:
FixedPoint: Implemented +=,-=,*=,/= operators
Text files modified:
   sandbox/fixed_point/boost/fixed_point/number.hpp | 137 ++++++++++++++++++++++++++++-----------
   sandbox/fixed_point/libs/fixed_point/example/ex_xx.cpp | 59 +++++++++++++++++
   2 files changed, 155 insertions(+), 41 deletions(-)

Modified: sandbox/fixed_point/boost/fixed_point/number.hpp
==============================================================================
--- sandbox/fixed_point/boost/fixed_point/number.hpp (original)
+++ sandbox/fixed_point/boost/fixed_point/number.hpp 2012-03-03 13:54:56 EST (Sat, 03 Mar 2012)
@@ -28,6 +28,7 @@
 #include <boost/integer.hpp>
 #include <boost/integer/static_log2.hpp>
 #include <boost/ratio/detail/mpl/abs.hpp>
+#include <limits>
 
 #include <boost/config.hpp>
 //#include <boost/fixed_point/config.hpp>
@@ -82,10 +83,10 @@
     namespace round
     {
       struct fastest {
- //BOOST_STATIC_CONSTEXPR std::round_to_nearest round_style = std::round_indeterminate;
+ BOOST_STATIC_CONSTEXPR std::float_round_style round_style = std::round_indeterminate;
       };
       struct negative {
- //BOOST_STATIC_CONSTEXPR std::round_to_nearest round_style = std::round_toward_infinity;
+ BOOST_STATIC_CONSTEXPR std::float_round_style round_style = std::round_toward_infinity;
         template <typename From, typename To>
         static typename To::underlying_type round(From const& rhs)
         {
@@ -111,7 +112,7 @@
         }
       };
       struct truncated {
- //BOOST_STATIC_CONSTEXPR std::round_to_nearest round_style = std::round_toward_zero;
+ BOOST_STATIC_CONSTEXPR std::float_round_style round_style = std::round_toward_zero;
         template <typename From, typename To>
         static typename To::underlying_type round(From const& rhs)
         {
@@ -130,7 +131,7 @@
         }
       };
       struct positive {
- //BOOST_STATIC_CONSTEXPR std::round_to_nearest round_style = std::round_toward_neg_infinity;
+ BOOST_STATIC_CONSTEXPR std::float_round_style round_style = std::round_toward_neg_infinity;
         template <typename From, typename To>
         static typename To::underlying_type round(From const& rhs)
         {
@@ -157,14 +158,17 @@
           }
         }
       };
- struct classic {
- //BOOST_STATIC_CONSTEXPR std::round_to_nearest round_style = std::round_to_nearest;
+ struct nearest_half_up {
+ BOOST_STATIC_CONSTEXPR std::float_round_style round_style = std::round_to_nearest;
+ };
+ struct nearest_half_down {
+ BOOST_STATIC_CONSTEXPR std::float_round_style round_style = std::round_to_nearest;
       };
- struct near_even {
- //BOOST_STATIC_CONSTEXPR std::round_to_nearest round_style = std::round_to_nearest;
+ struct nearest_even {
+ BOOST_STATIC_CONSTEXPR std::float_round_style round_style = std::round_to_nearest;
       };
       struct nearest_odd {
- //BOOST_STATIC_CONSTEXPR std::round_to_nearest round_style;
+ BOOST_STATIC_CONSTEXPR std::float_round_style round_style = std::round_to_nearest;
       };
     }
     namespace overflow
@@ -353,6 +357,55 @@
     template <int Range, int Resolution, typename Rounding=round::negative, typename Overflow=overflow::exception, typename Optimization=optimization::space>
     class signed_number;
 
+ template <
+ typename Res,
+ int R1, int P1, typename RP1, typename OP1, typename Opt1,
+ int R2, int P2, typename RP2, typename OP2, typename Opt2>
+ inline
+ Res
+ divide(signed_number<R1,P1,RP1,OP1,Opt1> const& lhs, signed_number<R2,P2,RP2,OP2,Opt2> const& rhs);
+ template <
+ typename Res,
+ int R1, int P1, typename RP1, typename OP1, typename Opt1,
+ int R2, int P2, typename RP2, typename OP2, typename Opt2>
+ inline
+ Res
+ divide(signed_number<R1,P1,RP1,OP1,Opt1> const& lhs, signed_number<R2,P2,RP2,OP2,Opt2> const& rhs);
+
+ template <
+ typename Res,
+ int R1, int P1, typename RP1, typename OP1, typename Opt1,
+ int R2, int P2, typename RP2, typename OP2, typename Opt2>
+ inline
+ Res
+ divide(signed_number<R1,P1,RP1,OP1,Opt1> const& lhs, unsigned_number<R2,P2,RP2,OP2,Opt2> const& rhs);
+
+ template <
+ typename Res,
+ int R1, int P1, typename RP1, typename OP1, typename Opt1,
+ int R2, int P2, typename RP2, typename OP2, typename Opt2>
+ inline
+ Res
+ divide(unsigned_number<R1,P1,RP1,OP1,Opt1> const& lhs, signed_number<R2,P2,RP2,OP2,Opt2> const& rhs);
+
+ }
+}
+
+#define BOOST_TYPEOF_SILENT
+#include <boost/typeof/typeof.hpp>
+
+#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
+
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::fixed_point::signed_number, (int)(int)(typename)(typename)(typename))
+BOOST_TYPEOF_REGISTER_TEMPLATE(boost::fixed_point::unsigned_number, (int)(int)(typename)(typename)(typename))
+
+
+///////////////////////////////////////
+
+namespace boost {
+ namespace fixed_point {
+
+
     // named parameter like class, allowing to make a specific overload when the integer must be taken by the index.
     template <typename T>
     struct index_tag
@@ -846,10 +899,13 @@
 
         BOOST_CONSTEXPR To operator()(const From& rhs) const
         {
+ std::cout << __FILE__ << "[" <<__LINE__<<"] "<< int(rhs.count()) <<std::endl;
           // Overflow
           underlying_type indx(((rhs.count()) >> (P2-P1)));
+ std::cout << __FILE__ << "[" <<__LINE__<<"] "<< int(indx) <<std::endl;
           if (rhs.count() > (typename From::underlying_type(To::max_index)<<(P2-P1)))
           {
+ std::cout << __FILE__ << "[" <<__LINE__<<"] "<< int(typename From::underlying_type(To::max_index)<<(P2-P1)) <<std::endl;
             return To(index(OP2::template on_positive_overflow<To,underlying_type>(indx)));
           }
           if (rhs.count() < (typename From::underlying_type(To::min_index)<<(P2-P1)))
@@ -1118,18 +1174,6 @@
       BOOST_STATIC_CONSTEXPR underlying_type max_index = detail::signed_integer_traits<underlying_type,Range,Resolution>::const_max;
 
 
- template <int R, int P, typename RP, typename OP, typename Opt>
- static bool positive_overflows(signed_number<R,P,RP,OP,Opt> const& rhs)
- {
- return false;
- }
- template <int R, int P, typename RP, typename OP, typename Opt>
- static bool negative_overflows(signed_number<R,P,RP,OP,Opt> const& rhs)
- {
- return false;
- }
-
-
       //! construct/copy/destroy:
       signed_number() {} // = default;
       signed_number(signed_number const& rhs) : value_(rhs.value_) {} // = default;
@@ -1226,6 +1270,10 @@
         return signed_number(index(max_index));
       }
 
+ underlying_type integral_part() const
+ {
+ return count() >> resolution_exp;
+ }
 
 #if 0
 
@@ -1362,22 +1410,26 @@
 #endif
       signed_number& operator += (signed_number const& rhs)
       {
- value_ += rhs.count();
+ signed_number tmp = number_cast<signed_number>(*this+rhs);
+ value_ = tmp.count();
         return *this;
       }
       signed_number& operator-=(const signed_number& rhs)
       {
- value_ -= rhs.count();
+ signed_number tmp = number_cast<signed_number>(*this-rhs);
+ value_ = tmp.count();
         return *this;
       }
       signed_number& operator*=(const signed_number& rhs)
       {
- value_ *= rhs.count();
+ signed_number tmp = number_cast<signed_number>((*this) * rhs);
+ value_ = tmp.count();
         return *this;
       }
       signed_number& operator/=(const signed_number& rhs)
       {
- value_ /= rhs.count();
+ signed_number tmp = divide<signed_number>(*this , rhs);
+ value_ = tmp.count();
         return *this;
       }
     protected:
@@ -1476,6 +1528,11 @@
         return unsigned_number(index(max_index));
       }
 
+ underlying_type integral_part() const
+ {
+ return count() >> resolution_exp;
+ }
+
 #if 0
 
       //! conversion factor.
@@ -1612,22 +1669,26 @@
 #endif
       unsigned_number& operator += (unsigned_number const& rhs)
       {
- value_ += rhs.count();
+ unsigned_number tmp = number_cast<unsigned_number>((*this) + rhs);
+ value_ = tmp.count();
         return *this;
       }
- unsigned_number& operator-=(const unsigned_number& rhs)
+ unsigned_number& operator-=(unsigned_number const& rhs)
       {
- value_ -= rhs.count();
+ unsigned_number tmp = number_cast<unsigned_number>((*this) - rhs);
+ value_ = tmp.count();
         return *this;
       }
- unsigned_number& operator*=(const unsigned_number& rhs)
+ unsigned_number& operator*=(unsigned_number const& rhs)
       {
- value_ *= rhs.count();
+ unsigned_number tmp = number_cast<unsigned_number>((*this) * rhs);
+ value_ = tmp.count();
         return *this;
       }
- unsigned_number& operator/=(const unsigned_number& rhs)
+ unsigned_number& operator/=(unsigned_number const& rhs)
       {
- value_ /= rhs.count();
+ unsigned_number tmp = divide<unsigned_number>(*this, rhs);
+ value_ += tmp.count();
         return *this;
       }
     protected:
@@ -1960,9 +2021,9 @@
       typedef typename result_type::underlying_type underlying_type;
 
       typedef typename common_type<signed_number<R1,P1,RP1,OP1,Opt1>, signed_number<R2,P2,RP2,OP2,Opt2> >::type CT;
- BOOST_STATIC_CONSTEXPR int P = Res::resolution_exp;
+ //BOOST_STATIC_CONSTEXPR int P = Res::resolution_exp;
 
- BOOST_STATIC_ASSERT((Res::digits>=(CT::digits-P)));
+ //BOOST_STATIC_ASSERT((Res::digits>=(CT::digits-P)));
       BOOST_STATIC_ASSERT((Res::is_signed==CT::is_signed));
       BOOST_ASSERT_MSG(CT(rhs).count()!=0, "Division by 0");
 
@@ -2255,6 +2316,7 @@
     template <typename To, typename From>
     To number_cast(From const& f)
     {
+ //std::cout << __FILE__ << "[" <<__LINE__<<"] "<< f.count() <<std::endl;
       return fixed_point::detail::number_cast<From, To>()(f);
     }
   }
@@ -2302,11 +2364,4 @@
   };
 }
 
-#define BOOST_TYPEOF_SILENT
-#include <boost/typeof/typeof.hpp>
-
-#include BOOST_TYPEOF_INCREMENT_REGISTRATION_GROUP()
-
-BOOST_TYPEOF_REGISTER_TEMPLATE(boost::fixed_point::signed_number, (int)(int)(typename)(typename)(typename))
-BOOST_TYPEOF_REGISTER_TEMPLATE(boost::fixed_point::unsigned_number, (int)(int)(typename)(typename)(typename))
 #endif // header

Modified: sandbox/fixed_point/libs/fixed_point/example/ex_xx.cpp
==============================================================================
--- sandbox/fixed_point/libs/fixed_point/example/ex_xx.cpp (original)
+++ sandbox/fixed_point/libs/fixed_point/example/ex_xx.cpp 2012-03-03 13:54:56 EST (Sat, 03 Mar 2012)
@@ -329,6 +329,14 @@
     signed_number<3,-1> n3 = n1 + n2;
     BOOST_TEST(n3.count()==-14);
   }
+ // +=
+ {
+ std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+ signed_number<2,-1> n1((index(3)));
+ signed_number<2,-1> n2((index(3)));
+ n1+=n2;
+ BOOST_TEST(n1.count()==6);
+ }
   // minus
   {
     std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
@@ -344,6 +352,15 @@
     signed_number<3,-2> n3 = n1 - n2;
     BOOST_TEST(n3.count()==0);
   }
+ // -=
+ {
+ std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+ signed_number<2,-1> n1((index(7)));
+ signed_number<2,-1> n2((index(7)));
+ n1-=n2;
+ std::cout << int(n1.count()) << std::endl;
+ BOOST_TEST(n1.count()==0);
+ }
   // multiply
   {
     std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
@@ -377,6 +394,48 @@
     std::cout << int(n3.count()) << std::endl;
     BOOST_TEST(n3.count()==49);
   }
+
+ // *=
+ {
+ std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+ signed_number<6,-1, round::truncated> n1((index(7)));
+ signed_number<6,-1, round::truncated> n2((index(3)));
+ n1*=n2;
+ std::cout << int(n1.count()) << std::endl;
+ BOOST_TEST(n1.count()==10); // The exact result 21/4 rounds to 10/2.
+ }
+ {
+ std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+ signed_number<6,-1, round::truncated> n1((index(7)));
+ unsigned_number<6,-1, round::truncated> n2((index(3)));
+ n1*=n2;
+ std::cout << int(n1.count()) << std::endl;
+ BOOST_TEST(n1.count()==10); // The exact result 21/4 rounds to 10/2.
+ }
+// {
+// std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+// unsigned_number<6,-1, round::truncated> n1((index(7)));
+// signed_number<6,-1, round::truncated> n2((index(3)));
+// n1*=n2; // compile fails
+// std::cout << int(n1.count()) << std::endl;
+// BOOST_TEST(n1.count()==10); // The exact result 21/4 rounds to 10/2.
+// }
+ // /=
+ {
+ std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+ signed_number<3,-2, round::truncated> n1((index(1)));
+ signed_number<3,-2, round::truncated> n2((index(7)));
+ n1 /= n2;
+ BOOST_TEST(n1.count()==0);
+ }
+ {
+ std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+ signed_number<3,-2, round::truncated> n1((index(7)));
+ signed_number<3,-2, round::truncated> n2((index(3)));
+ n1 /= n2;
+ std::cout << int(n1.count()) << std::endl;
+ BOOST_TEST(n1.count()==9); // 7*4/3
+ }
   // divide
   {
     std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;


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