$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
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;