$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
Subject: [Boost-commit] svn:boost r77170 - in sandbox/fixed_point: boost/fixed_point libs/fixed_point/example
From: vicente.botet_at_[hidden]
Date: 2012-03-03 05:55:24
Author: viboes
Date: 2012-03-03 05:55:23 EST (Sat, 03 Mar 2012)
New Revision: 77170
URL: http://svn.boost.org/trac/boost/changeset/77170
Log:
FixedPoint: Add divide with round truncate,positive and negative
Text files modified: 
   sandbox/fixed_point/boost/fixed_point/number.hpp       |   266 ++++++++++++++++++++++----------------- 
   sandbox/fixed_point/libs/fixed_point/example/ex_xx.cpp |   141 +++++++++++++++++++-                    
   2 files changed, 281 insertions(+), 126 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 05:55:23 EST (Sat, 03 Mar 2012)
@@ -40,6 +40,42 @@
 {
   namespace fixed_point
   {
+    namespace detail {
+      template <typename CT, int Bits, int P, bool IsSigned=is_signed<CT>::value, bool IsPositive=(P>0)>
+      struct shift_impl;
+      template <typename CT, int Bits, int P, bool IsSigned>
+      struct shift_impl<CT,Bits, P, IsSigned, true> {
+        BOOST_STATIC_CONSTEXPR std::size_t digits = Bits-P;
+        typedef CT result_type;
+        static  CT apply(CT v)
+        {
+          return v >> P;
+        }
+      };
+      template <typename CT, int Bits, int P>
+      struct shift_impl<CT,Bits, P,true,false> {
+        BOOST_STATIC_CONSTEXPR std::size_t digits = Bits-P;
+        typedef typename ::boost::int_t<Bits-P>::fast result_type;
+        static result_type apply(CT v)
+        {
+          return result_type(v) << -P;
+        }
+      };
+      template <typename CT, int Bits, int P>
+      struct shift_impl<CT,Bits, P,false,false> {
+        BOOST_STATIC_CONSTEXPR std::size_t digits = Bits-P;
+        typedef typename ::boost::uint_t<Bits-P>::fast result_type;
+        static  result_type apply(CT v)
+        {
+          return result_type(v) << -P;
+        }
+      };
+      template <typename UT, int Bits, int P>
+      typename shift_impl<UT,Bits,P>::result_type shift(UT v) {
+        return shift_impl<UT,Bits,P>::apply(v);
+      }
+    }
+
     struct positive_overflow {};
     struct negative_overflow {};
 
@@ -57,6 +93,22 @@
 
           return typename To::underlying_type(rhs.count()) >> d;
         }
+        template <typename To, typename From>
+        static typename To::underlying_type round_divide(From const& lhs, From const& rhs)
+        {
+          typedef typename To::underlying_type result_type;
+          result_type ci = detail::shift<typename From::underlying_type, From::digits, To::resolution_exp>(lhs.count()) / rhs.count();
+          if (ci>=0 )
+          {
+            return ci;
+          } else {
+            result_type ri = detail::shift<typename From::underlying_type, From::digits, To::resolution_exp>(lhs.count()) % rhs.count();
+            if (ri==0)
+              return ci;
+            else
+              return ci-1;
+          }
+        }
       };
       struct truncated {
         //BOOST_STATIC_CONSTEXPR std::round_to_nearest  round_style = std::round_toward_zero;
@@ -69,6 +121,13 @@
 
           return s * (m >> d);
         }
+        template <typename To, typename From>
+        static typename To::underlying_type round_divide(From const& lhs, From const& rhs)
+        {
+          typedef typename To::underlying_type result_type;
+          result_type ci = detail::shift<typename From::underlying_type, From::digits, To::resolution_exp>(lhs.count()) / rhs.count();
+          return ci;
+        }
       };
       struct positive {
         //BOOST_STATIC_CONSTEXPR std::round_to_nearest  round_style = std::round_toward_neg_infinity;
@@ -81,6 +140,22 @@
 
           return (i+w) >> d;
         }
+        template <typename To, typename From>
+        static typename To::underlying_type round_divide(From const& lhs, From const& rhs)
+        {
+          typedef typename To::underlying_type result_type;
+          result_type ci = detail::shift<typename From::underlying_type, From::digits, To::resolution_exp>(lhs.count()) / rhs.count();
+          if (ci>=0 )
+          {
+            result_type ri = detail::shift<typename From::underlying_type, From::digits, To::resolution_exp>(lhs.count()) % rhs.count();
+            if (ri==0)
+              return ci;
+            else
+              return ci+1;
+          } else {
+              return ci;
+          }
+        }
       };
       struct classic {
         //BOOST_STATIC_CONSTEXPR std::round_to_nearest  round_style =  std::round_to_nearest;
@@ -95,6 +170,7 @@
     namespace overflow
     {
       struct impossible {
+        BOOST_STATIC_CONSTEXPR bool is_modulo = false;
         template <typename T, typename U>
         static typename T::underlying_type on_negative_overflow(U value)
         {
@@ -109,6 +185,7 @@
         }
       };
       struct undefined {
+        BOOST_STATIC_CONSTEXPR bool is_modulo = false;
         template <typename T, typename U>
         static typename T::underlying_type on_negative_overflow(U value)
         {
@@ -165,6 +242,7 @@
         };
       }
       struct modulus {
+        BOOST_STATIC_CONSTEXPR bool is_modulo = true;
         template <typename T, typename U>
         static typename T::underlying_type on_negative_overflow(U val)
         {
@@ -177,6 +255,7 @@
         }
       };
       struct saturate {
+        BOOST_STATIC_CONSTEXPR bool is_modulo = false;
         template <typename T, typename U>
         static typename T::underlying_type on_negative_overflow(U value)
         {
@@ -190,6 +269,7 @@
 
       };
       struct exception {
+        BOOST_STATIC_CONSTEXPR bool is_modulo = false;
         template <typename T, typename U>
         static typename T::underlying_type on_negative_overflow(U value)
         {
@@ -295,17 +375,17 @@
     {
       template <typename T, int Range, int Resolution >
       struct signed_integer_traits {
-        BOOST_STATIC_CONSTEXPR std::size_t bits = (Range-Resolution)+1;
-        BOOST_STATIC_ASSERT_MSG((sizeof(T)*8)>=bits, LLLL);
-        //BOOST_MPL_ASSERT_MSG((sizeof(T)*8)>=bits, LLLL, (mpl::int_<sizeof(T)*8>, mpl::int_<bits>));
-        BOOST_STATIC_CONSTEXPR T const_max = (1<<(bits-1)) - 1;
+        BOOST_STATIC_CONSTEXPR std::size_t digits = (Range-Resolution)+1;
+        BOOST_STATIC_ASSERT_MSG((sizeof(T)*8)>=digits, "LLLL");
+        //BOOST_MPL_ASSERT_MSG((sizeof(T)*8)>=digits, LLLL, (mpl::int_<sizeof(T)*8>, mpl::int_<digits>));
+        BOOST_STATIC_CONSTEXPR T const_max = (1<<(digits-1)) - 1;
         BOOST_STATIC_CONSTEXPR T const_min = -const_max;
 
       };
       template <typename T, int Range, int Resolution >
       struct unsigned_integer_traits {
-        BOOST_STATIC_CONSTEXPR std::size_t bits = (Range-Resolution);
-        BOOST_STATIC_CONSTEXPR T const_max = (1<<(bits)) - 1;
+        BOOST_STATIC_CONSTEXPR std::size_t digits = (Range-Resolution);
+        BOOST_STATIC_CONSTEXPR T const_max = (1<<(digits)) - 1;
         BOOST_STATIC_CONSTEXPR T const_min = 0;
 
       };
@@ -322,6 +402,8 @@
         // name the template parameters
         BOOST_STATIC_CONSTEXPR int range_exp = Range;
         BOOST_STATIC_CONSTEXPR int resolution_exp = Resolution;
+        BOOST_STATIC_CONSTEXPR int digits = range_exp-resolution_exp+1;
+
         typedef Optimization optimization_type;
 
         BOOST_STATIC_CONSTEXPR underlying_type min_index = detail::signed_integer_traits<underlying_type,Range,Resolution>::const_min;
@@ -400,7 +482,6 @@
 
         BOOST_CONSTEXPR To operator()(const From& rhs) const
         {
-          std::cout << __FILE__ << "[" <<__LINE__<<"] "<< P1-P2 <<std::endl;
           // No overflow and no round needed
           return To(index(underlying_type(rhs.count()) << (P1-P2)));
         }
@@ -435,7 +516,6 @@
 
         BOOST_CONSTEXPR To operator()(const From& rhs) const
         {
-          std::cout << __FILE__ << "[" <<__LINE__<<"] "<< P1-P2 <<std::endl;
           // No overflow and no round needed
           return To(index(underlying_type(rhs.count()) << (P1-P2)));
         }
@@ -454,7 +534,6 @@
 
         BOOST_CONSTEXPR To operator()(const From& rhs) const
         {
-          std::cout << __FILE__ << "[" <<__LINE__<<"] "<< P1-P2 <<std::endl;
 
           underlying_type indx((underlying_type(rhs.count()) << (P1-P2)));
           // Overflow
@@ -482,7 +561,6 @@
 
         BOOST_CONSTEXPR To operator()(const From& rhs) const
         {
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
 
           underlying_type indx((underlying_type(rhs.count()) << (P1-P2)));
           // Overflow impossible
@@ -512,7 +590,6 @@
 
         BOOST_CONSTEXPR To operator()(const From& rhs) const
         {
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
 
           underlying_type indx((underlying_type(rhs.count()) << (P1-P2)));
           // Overflow impossible
@@ -542,7 +619,6 @@
 
         BOOST_CONSTEXPR To operator()(const From& rhs) const
         {
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
 
           underlying_type indx((underlying_type(rhs.count()) << (P1-P2)));
           // Overflow
@@ -568,7 +644,6 @@
 
         BOOST_CONSTEXPR To operator()(const From& rhs) const
         {
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
 
           underlying_type indx((underlying_type(rhs.count()) << (P1-P2)));
           // Overflow
@@ -597,7 +672,6 @@
 
         BOOST_CONSTEXPR To operator()(const From& rhs) const
         {
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
           // Overflow could be possible because more resolution implies a bigger range when the range exponents are the same.
           underlying_type indx(((rhs.count()) >> (P2-P1)));
           if (rhs.count() > (typename From::underlying_type(To::max_index)<<(P2-P1)))
@@ -610,9 +684,7 @@
           }
 
           // Round
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
           To res((index(RP2::template round<From,To>(rhs))));
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
           return res;
         }
       };
@@ -629,13 +701,9 @@
 
         BOOST_CONSTEXPR To operator()(const From& rhs) const
         {
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
           // No overflow check needed as the case for the same range exponent is explicit above
 
           // Round
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<RP2::template round<From,To>(rhs)  <<std::endl;
-          To res((index(RP2::template round<From,To>(rhs))));
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
           return To(index(RP2::template round<From,To>(rhs)));
         }
       };
@@ -655,7 +723,6 @@
 
         BOOST_CONSTEXPR To operator()(const From& rhs) const
         {
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
           // Overflow
           underlying_type indx(((rhs.count()) >> (P2-P1)));
           if (rhs.count() > (typename From::underlying_type(To::max_index)<<(P2-P1)))
@@ -668,10 +735,7 @@
           }
 
           // Round
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
-          To res((index(RP2::template round<From,To>(rhs))));
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
-          return res;
+          return To((index(RP2::template round<From,To>(rhs))));
         }
       };
 
@@ -689,7 +753,6 @@
 
         BOOST_CONSTEXPR To operator()(const From& rhs) const
         {
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
           // Overflow could be possible because more resolution implies a bigger range when the range exponents are the same.
           underlying_type indx(((rhs.count()) >> (P2-P1)));
           if (rhs.count() > (typename From::underlying_type(To::max_index)<<(P2-P1)))
@@ -698,10 +761,7 @@
           }
 
           // Round
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
-          To res((index(RP2::template round<From,To>(rhs))));
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
-          return res;
+          return To((index(RP2::template round<From,To>(rhs))));
         }
       };
       template <int R1, int P1, typename RP1, typename OP1, typename Opt1,
@@ -717,13 +777,9 @@
 
         BOOST_CONSTEXPR To operator()(const From& rhs) const
         {
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
           // No overflow check needed as the case for the same range exponent is explicit above
 
           // Round
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<RP2::template round<From,To>(rhs)  <<std::endl;
-          To res((index(RP2::template round<From,To>(rhs))));
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
           return To(index(RP2::template round<From,To>(rhs)));
         }
       };
@@ -743,7 +799,6 @@
 
         BOOST_CONSTEXPR To operator()(const From& rhs) const
         {
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
           // Overflow could be possible because more resolution implies a bigger range when the range exponents are the same.
           underlying_type indx(((rhs.count()) >> (P2-P1)));
           if (rhs.count() > (typename From::underlying_type(To::max_index)<<(P2-P1)))
@@ -752,10 +807,7 @@
           }
 
           // Round
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
-          To res((index(RP2::template round<From,To>(rhs))));
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
-          return res;
+          return To((index(RP2::template round<From,To>(rhs))));
         }
       };
       template <int R1, int P1, typename RP1, typename OP1, typename Opt1,
@@ -771,13 +823,9 @@
 
         BOOST_CONSTEXPR To operator()(const From& rhs) const
         {
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
           // No overflow check needed as the case for the same range exponent is explicit above
 
           // Round
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<RP2::template round<From,To>(rhs)  <<std::endl;
-          To res((index(RP2::template round<From,To>(rhs))));
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
           return To(index(RP2::template round<From,To>(rhs)));
         }
       };
@@ -798,7 +846,6 @@
 
         BOOST_CONSTEXPR To operator()(const From& rhs) const
         {
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
           // Overflow
           underlying_type indx(((rhs.count()) >> (P2-P1)));
           if (rhs.count() > (typename From::underlying_type(To::max_index)<<(P2-P1)))
@@ -827,7 +874,6 @@
 
         BOOST_CONSTEXPR To operator()(const From& rhs) const
         {
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
           // Overflow
           underlying_type indx(((rhs.count()) >> (P2-P1)));
           if (rhs.count() > (typename From::underlying_type(To::max_index)<<(P2-P1)))
@@ -853,7 +899,6 @@
 
         BOOST_CONSTEXPR To operator()(const From& rhs) const
         {
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
           // Overflow
           underlying_type indx(((rhs.count()) >> (P2-P1)));
           if (rhs.count() > (typename From::underlying_type(To::max_index)<<(P2-P1)))
@@ -883,7 +928,6 @@
 
         BOOST_CONSTEXPR To operator()(const From& rhs) const
         {
-          std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
           // Overflow
           underlying_type indx(((rhs.count()) >> (P2-P1)));
           if (rhs.count() > (typename From::underlying_type(To::max_index)<<(P2-P1)))
@@ -970,21 +1014,24 @@
   };
 
   template <>
-  struct common_type<fixed_point::round::fastest,fixed_point::round::fastest>
+  struct common_type<fixed_point::round::truncated,fixed_point::round::truncated>
   {
-    typedef fixed_point::round::fastest type;
+    typedef fixed_point::round::truncated type;
   };
   template <typename Round>
-  struct common_type<Round,fixed_point::round::fastest>
+  struct common_type<Round,fixed_point::round::truncated>
   {
-    typedef Round type;
+    typedef fixed_point::round::truncated type;
   };
   template <typename Round>
-  struct common_type<fixed_point::round::fastest,Round>
+  struct common_type<fixed_point::round::truncated,Round>
   {
-    typedef Round type;
+    typedef fixed_point::round::truncated type;
   };
 
+
+
+
   template <int R1, int P1, typename RP1, typename OP1, typename Opt1,
             int R2, int P2, typename RP2, typename OP2, typename Opt2>
   struct common_type<
@@ -1065,6 +1112,8 @@
       typedef Overflow overflow_type;
       typedef Optimization optimization_type;
 
+      BOOST_STATIC_CONSTEXPR bool is_signed = boost::is_signed<underlying_type>::value;
+      BOOST_STATIC_CONSTEXPR std::size_t digits = detail::signed_integer_traits<underlying_type,Range,Resolution>::digits;
       BOOST_STATIC_CONSTEXPR underlying_type min_index = detail::signed_integer_traits<underlying_type,Range,Resolution>::const_min;
       BOOST_STATIC_CONSTEXPR underlying_type max_index = detail::signed_integer_traits<underlying_type,Range,Resolution>::const_max;
 
@@ -1098,8 +1147,6 @@
         )
         : value_(fixed_point::detail::number_cast<signed_number<R,P,RP,OP,Opt>, signed_number, true, true>()(rhs).count())
       {
-        std::cout << __FILE__ << "[" <<__LINE__<<"] "<< P << std::endl;
-
       }
       //! implicit constructor from a signed_number with no larger range and no better resolution
       template <int R, int P, typename RP, typename OP, typename Opt>
@@ -1113,8 +1160,6 @@
         )
         : value_(fixed_point::detail::number_cast<unsigned_number<R,P,RP,OP,Opt>, signed_number, true, true>()(rhs).count())
       {
-        std::cout << __FILE__ << "[" <<__LINE__<<"] "<< P << std::endl;
-
       }
 
       //! explicit constructor from a signed_number with larger range or better resolution
@@ -1132,8 +1177,6 @@
             mpl::greater_equal < mpl::int_<P>, mpl::int_<Resolution> >::value
             >()(rhs).count())
       {
-        std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
-
       }
       //! explicit constructor from a signed_number with larger range or better resolution
       template <int R, int P, typename RP, typename OP, typename Opt>
@@ -1150,8 +1193,6 @@
             mpl::greater_equal < mpl::int_<P>, mpl::int_<Resolution> >::value
             >()(rhs).count())
       {
-        std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
-
       }
 
       ~signed_number() {} //= default;
@@ -1161,9 +1202,9 @@
       template <typename UT>
       explicit signed_number(index_tag<UT> i) : value_(i.get())
       {
-        std::cout << __FILE__ << "[" <<__LINE__<<"] "<<int(min_index) <<std::endl;
-        std::cout << __FILE__ << "[" <<__LINE__<<"] "<<int(max_index) <<std::endl;
-        std::cout << __FILE__ << "[" <<__LINE__<<"] "<<int(i.get()) <<std::endl;
+        //std::cout << __FILE__ << "[" <<__LINE__<<"] "<<int(min_index) <<std::endl;
+        //std::cout << __FILE__ << "[" <<__LINE__<<"] "<<int(max_index) <<std::endl;
+        //std::cout << __FILE__ << "[" <<__LINE__<<"] "<<int(i.get()) <<std::endl;
         BOOST_ASSERT(i.get()>=min_index);
         BOOST_ASSERT(i.get()<=max_index);
       }
@@ -1362,6 +1403,8 @@
       typedef Overflow overflow_type;
       typedef Optimization optimization_type;
 
+      BOOST_STATIC_CONSTEXPR bool is_signed = boost::is_signed<underlying_type>::value;
+      BOOST_STATIC_CONSTEXPR std::size_t digits = detail::unsigned_integer_traits<underlying_type,Range,Resolution>::digits;
       BOOST_STATIC_CONSTEXPR underlying_type min_index = detail::unsigned_integer_traits<underlying_type,Range,Resolution>::const_min;
       BOOST_STATIC_CONSTEXPR underlying_type max_index = detail::unsigned_integer_traits<underlying_type,Range,Resolution>::const_max;
 
@@ -1383,8 +1426,6 @@
         )
         : value_(fixed_point::detail::number_cast<unsigned_number<R,P,RP,OP,Opt>, unsigned_number, true, true>()(rhs).count())
       {
-        std::cout << __FILE__ << "[" <<__LINE__<<"] "<< P << std::endl;
-
       }
 
       //! explicit constructor from a unsigned_number with larger range or better resolution
@@ -1402,8 +1443,6 @@
             mpl::greater_equal < mpl::int_<P>, mpl::int_<Resolution> >::value
             >()(rhs).count())
       {
-        std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
-
       }
 
       ~unsigned_number() {} //= default;
@@ -1413,9 +1452,9 @@
       template <typename UT>
       explicit unsigned_number(index_tag<UT> i) : value_(i.get())
       {
-        std::cout << __FILE__ << "[" <<__LINE__<<"] "<<int(min_index) <<std::endl;
-        std::cout << __FILE__ << "[" <<__LINE__<<"] "<<int(max_index) <<std::endl;
-        std::cout << __FILE__ << "[" <<__LINE__<<"] "<<int(i.get()) <<std::endl;
+        //std::cout << __FILE__ << "[" <<__LINE__<<"] "<<int(min_index) <<std::endl;
+        //std::cout << __FILE__ << "[" <<__LINE__<<"] "<<int(max_index) <<std::endl;
+        //std::cout << __FILE__ << "[" <<__LINE__<<"] "<<int(i.get()) <<std::endl;
         BOOST_ASSERT(i.get()>=min_index);
         BOOST_ASSERT(i.get()<=max_index);
       }
@@ -1893,6 +1932,20 @@
       return result_type(index(underlying_type(lhs.count()) * rhs.count()));
     }
 
+    /*
+     * N = C*D+R
+     * P*N = P*C*D+P*R
+     * X=INT(P*N/D)=P*C
+     * X/P <= N/D < (X+1)/P
+     * 2X/2P <= N/D < 2(X+1)/2P
+     *
+     * exact    : X/P == N/D
+     * near_down: X/P < N/D < (2X+1)/2P
+     * half     :             (2X+1)/2P == N/D
+     * near_up  :             (2X+1)/2P < N/D < (X+1)/P
+     *
+     *
+     */
     //!  divide
 
     template <
@@ -1905,22 +1958,18 @@
     {
       typedef Res result_type;
       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_ASSERT((mpl::greater_equal<
-            mpl::int_<Res::range_exp>,
-            mpl::int_<R1-P2>
-          >::type::value));
-      BOOST_STATIC_ASSERT((mpl::less_equal<
-            mpl::int_<Res::resolution_exp>,
-            mpl::int_<P1-R2>
-          >::type::value));
+      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");
 
-      underlying_type ci = (underlying_type(CT(lhs).count()) << -P) / CT(rhs).count();
-      std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
-      return result_type(index(ci)); // ....
+//      underlying_type ci = detail::shift<typename CT::underlying_type, CT::digits, P>(CT(lhs).count()) / CT(rhs).count();
+//      return result_type(index(ci)); // ....
+      typedef typename result_type::rounding_type rounding_type;
+      return result_type(index(rounding_type::template round_divide<Res>(CT(lhs), CT(rhs))));
     }
 
     template <
@@ -1936,19 +1985,14 @@
       typedef typename common_type<unsigned_number<R1,P1,RP1,OP1,Opt1>, unsigned_number<R2,P2,RP2,OP2,Opt2> >::type CT;
       BOOST_STATIC_CONSTEXPR int P = Res::resolution_exp;
 
-      BOOST_STATIC_ASSERT((mpl::greater_equal<
-            mpl::int_<Res::range_exp>,
-            mpl::int_<R1-P2>
-          >::type::value));
-      BOOST_STATIC_ASSERT((mpl::less_equal<
-            mpl::int_<Res::resolution_exp>,
-            mpl::int_<P1-R2>
-          >::type::value));
+      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");
 
-      underlying_type ci = (underlying_type(CT(lhs).count()) << -P) / CT(rhs).count();
-      std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
-      return result_type(index(ci)); // ....
+//      underlying_type ci = detail::shift<typename CT::underlying_type, CT::digits, P>(CT(lhs).count()) / CT(rhs).count();
+//      return result_type(index(ci)); // ....
+      typedef typename result_type::rounding_type rounding_type;
+      return result_type(index(rounding_type::template round_divide<Res>(CT(lhs), CT(rhs))));
     }
 
     template <
@@ -1964,19 +2008,14 @@
       typedef typename common_type<signed_number<R1,P1,RP1,OP1,Opt1>, unsigned_number<R2,P2,RP2,OP2,Opt2> >::type CT;
       BOOST_STATIC_CONSTEXPR int P = Res::resolution_exp;
 
-      BOOST_STATIC_ASSERT((mpl::greater_equal<
-            mpl::int_<Res::range_exp>,
-            mpl::int_<R1-P2>
-          >::type::value));
-      BOOST_STATIC_ASSERT((mpl::less_equal<
-            mpl::int_<Res::resolution_exp>,
-            mpl::int_<P1-R2>
-          >::type::value));
+      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");
 
-      underlying_type ci = (underlying_type(CT(lhs).count()) << -P) / CT(rhs).count();
-      std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
-      return result_type(index(ci)); // ....
+//      underlying_type ci = detail::shift<typename CT::underlying_type, CT::digits, P>(CT(lhs).count()) / CT(rhs).count();
+//      return result_type(index(ci)); // ....
+      typedef typename result_type::rounding_type rounding_type;
+      return result_type(index(rounding_type::template round_divide<Res>(CT(lhs), CT(rhs))));
     }
 
     template <
@@ -1992,19 +2031,14 @@
       typedef typename common_type<unsigned_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_ASSERT((mpl::greater_equal<
-            mpl::int_<Res::range_exp>,
-            mpl::int_<R1-P2>
-          >::type::value));
-      BOOST_STATIC_ASSERT((mpl::less_equal<
-            mpl::int_<Res::resolution_exp>,
-            mpl::int_<P1-R2>
-          >::type::value));
+      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");
 
-      underlying_type ci = (underlying_type(CT(lhs).count()) << -P) / CT(rhs).count();
-      std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
-      return result_type(index(ci)); // ....
+//      underlying_type ci = detail::shift<typename CT::underlying_type, CT::digits, P>(CT(lhs).count()) / CT(rhs).count();
+//      return result_type(index(ci)); // ....
+      typedef typename result_type::rounding_type rounding_type;
+      return result_type(index(rounding_type::template round_divide<Res>(CT(lhs), CT(rhs))));
     }
 
     //!  /
@@ -2229,7 +2263,7 @@
 namespace std {
   // numeric limits trait specializations
   template <int R, int P, typename RP, typename OP, typename Opt>
-  class numeric_limits<boost::fixed_point::signed_number<R,P,RP,OP,Opt> >
+  struct numeric_limits<boost::fixed_point::signed_number<R,P,RP,OP,Opt> >
   {
     typedef boost::fixed_point::signed_number<R,P,RP,OP,Opt> rep;
   public:
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 05:55:23 EST (Sat, 03 Mar 2012)
@@ -382,25 +382,145 @@
     std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
     signed_number<2,-1> n1((index(1)));
     signed_number<2,-1> n2((index(7)));
-    signed_number<3,-6> n3 = divide<signed_number<3,-6> >(n1,n2);
+    signed_number<3,-2> n3 = divide<signed_number<3,-2, round::truncated> >(n1,n2);
+    BOOST_TEST(n3.count()==0);
+  }
+  {
+    std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+    signed_number<2,-1> n1((index(1)));
+    signed_number<2,-1> n2((index(7)));
+    signed_number<3,-2> n3 = divide<signed_number<3,-2, round::negative> >(n1,n2);
+    BOOST_TEST(n3.count()==0);
+  }
+  {
+    std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+    signed_number<2,-1> n1((index(1)));
+    signed_number<2,-1> n2((index(7)));
+    signed_number<3,-2> n3 = divide<signed_number<3,-2, round::positive> >(n1,n2);
+    BOOST_TEST(n3.count()==1);
+  }
+  {
+    std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+    signed_number<2,-2> n1((index(15)));
+    signed_number<2,-2> n2((index(1)));
+    signed_number<4,-1> n3 = divide<signed_number<4,-1, round::truncated> >(n1,n2);
+    BOOST_TEST(n3.count()==30);
+  }
+  {
+    std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+    signed_number<2,-2> n1((index(15)));
+    signed_number<2,-2> n2((index(1)));
+    signed_number<4,-1> n3 = divide<signed_number<4,-1, round::negative> >(n1,n2);
+    std::cout << int(n3.count()) << std::endl;
+    BOOST_TEST(n3.count()==30);
+  }
+  {
+    std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+    signed_number<2,-2> n1((index(15)));
+    signed_number<2,-2> n2((index(1)));
+    signed_number<4,-1> n3 = divide<signed_number<4,-1, round::positive> >(n1,n2);
+    std::cout << int(n3.count()) << std::endl;
+    BOOST_TEST(n3.count()==30);
+  }
+  {
+    std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+    signed_number<2,-2> n1((index(-15)));
+    signed_number<2,-2> n2((index(1)));
+    signed_number<4,-1> n3 = divide<signed_number<4,-1, round::negative> >(n1,n2);
+    std::cout << int(n3.count()) << std::endl;
+    BOOST_TEST(n3.count()==-30);
+  }
+  {
+    std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+    signed_number<2,-2> n1((index(-15)));
+    signed_number<2,-2> n2((index(1)));
+    signed_number<4,-1> n3 = divide<signed_number<4,-1, round::positive> >(n1,n2);
+    std::cout << int(n3.count()) << std::endl;
+    BOOST_TEST(n3.count()==-30);
+  }
+  {
+    std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+    signed_number<2,-2> n1((index(15)));
+    signed_number<2,-2> n2((index(7)));
+    signed_number<4,-1> n3 = divide<signed_number<4,-1, round::negative> >(n1,n2);
+    std::cout << int(n3.count()) << std::endl;
+    BOOST_TEST(n3.count()==4);
+  }
+  {
+    std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+    signed_number<2,-2> n1((index(15)));
+    signed_number<2,-2> n2((index(7)));
+    signed_number<4,-1> n3 = divide<signed_number<4,-1, round::positive> >(n1,n2);
+    std::cout << int(n3.count()) << std::endl;
+    BOOST_TEST(n3.count()==5);
+  }
+  {
+    std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+    signed_number<2,-2> n1((index(-15)));
+    signed_number<2,-2> n2((index(7)));
+    signed_number<4,-1> n3 = divide<signed_number<4,-1, round::negative> >(n1,n2);
+    std::cout << int(n3.count()) << std::endl;
+    BOOST_TEST(n3.count()==-5);
+  }
+  {
+    std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+    signed_number<2,-2> n1((index(-15)));
+    signed_number<2,-2> n2((index(7)));
+    signed_number<4,-1> n3 = divide<signed_number<4,-1, round::positive> >(n1,n2);
+    std::cout << int(n3.count()) << std::endl;
+    BOOST_TEST(n3.count()==-4);
+  }
+  {
+    std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+    signed_number<2,-2> n1((index(15)));
+    signed_number<2,-1> n2((index(1)));
+    signed_number<4,-1> n3 = divide<signed_number<4,-1, round::truncated> >(n1,n2);
+    BOOST_TEST(n3.count()==15);
+  }
+  {
+    std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+    signed_number<2,-2> n1((index(15)));
+    signed_number<2,-1> n2((index(1)));
+    signed_number<4,0> n3 = divide<signed_number<4,0, round::truncated> >(n1,n2);
+    BOOST_TEST(n3.count()==7);
+  }
+  {
+    std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+    signed_number<2,-2> n1((index(15)));
+    signed_number<2,-1> n2((index(1)));
+    signed_number<4,1> n3 = divide<signed_number<4,1, round::truncated> >(n1,n2);
+    BOOST_TEST(n3.count()==3);
+  }
+  {
+    std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+    signed_number<2,-2> n1((index(15)));
+    signed_number<2,-1> n2((index(1)));
+    signed_number<4,2> n3 = divide<signed_number<4,2, round::truncated> >(n1,n2);
+    BOOST_TEST(n3.count()==1);
+  }
+  {
+    std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
+    signed_number<2,-1> n1((index(1)));
+    signed_number<2,-1> n2((index(7)));
+    signed_number<3,-6> n3 = divide<signed_number<3,-6, round::truncated> >(n1,n2);
     BOOST_TEST(n3.count()==9);
   }
   {
     unsigned_number<2,-1> n1((index(1)));
     unsigned_number<2,-2> n2((index(7)));
-    unsigned_number<4,-6> n3 = divide<unsigned_number<4,-6> >(n1,n2);
+    unsigned_number<4,-6> n3 = divide<unsigned_number<4,-6, round::truncated> >(n1,n2);
     BOOST_TEST(n3.count()==18);
   }
   {
     signed_number<2,-1> n1((index(1)));
     unsigned_number<2,-2> n2((index(7)));
-    signed_number<4,-6> n3 = divide<signed_number<4,-6> >(n1,n2);
+    signed_number<4,-6> n3 = divide<signed_number<4,-6, round::truncated> >(n1,n2);
     BOOST_TEST(n3.count()==18);
   }
   {
     unsigned_number<2,-1> n1((index(1)));
     signed_number<2,-2> n2((index(7)));
-    signed_number<4,-6> n3 = divide<signed_number<4,-6> >(n1,n2);
+    signed_number<4,-6> n3 = divide<signed_number<4,-6, round::truncated> >(n1,n2);
     BOOST_TEST(n3.count()==18);
   }
   {
@@ -412,14 +532,14 @@
   {
     signed_number<2,-1> n1((index(1)));
     signed_number<2,-2> n2((index(7)));
-    signed_number<6,-3> n3 = divide<signed_number<6,-3> >(n1,n2);
+    signed_number<6,-3> n3 = divide<signed_number<6,-3, round::truncated> >(n1,n2);
     std::cout << int(n3.count()) << std::endl;
     BOOST_TEST(n3.count()==2);
   }
   {
     signed_number<2,-1> n1((index(-1)));
     signed_number<2,-1> n2((index(7)));
-    signed_number<3,-6> n3 = divide<signed_number<3,-6> >(n1,n2);
+    signed_number<3,-6> n3 = divide<signed_number<3,-6, round::truncated> >(n1,n2);
     std::cout << int(n3.count()) << std::endl;
     BOOST_TEST(n3.count()==-9);
   }
@@ -432,19 +552,20 @@
   {
     signed_number<2,-1> n1((index(7)));
     signed_number<2,-1> n2((index(1)));
-    signed_number<3,-6> n3 = divide<signed_number<3,-6> >(n1,n2);
+    signed_number<3,-6> n3 = divide<signed_number<3,-6, round::truncated> >(n1,n2);
+    std::cout << int(n3.count()) << std::endl;
     BOOST_TEST(n3.count()==7*64);
   }
   {
     signed_number<4,1> n1((index(1)));
     signed_number<4,1> n2((index(7)));
-    signed_number<3,-6> n3 = divide<signed_number<3,-6> >(n1,n2);
+    signed_number<3,-6> n3 = divide<signed_number<3,-6, round::truncated> >(n1,n2);
     BOOST_TEST(n3.count()==9);
   }
   {
     signed_number<4,1> n1((index(1)));
     signed_number<4,1> n2((index(7)));
-    signed_number<3,-3> n3 = divide<signed_number<3,-3> >(n1,n2);
+    signed_number<3,-3> n3 = divide<signed_number<3,-3, round::truncated> >(n1,n2);
     BOOST_TEST(n3.count()==1);
   }
   {
@@ -452,7 +573,7 @@
     signed_number<4,1> n2((index(1)));
     std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
     std::cout << int(n2.count()) << std::endl;
-    signed_number<3,-6> n3 = divide<signed_number<3,-6> >(n1,n2);
+    signed_number<3,-6> n3 = divide<signed_number<3,-6, round::truncated> >(n1,n2);
     std::cout << __FILE__ << "[" <<__LINE__<<"]"<<std::endl;
     std::cout << int(n3.count()) << std::endl;
     BOOST_TEST(n3.count()==7*64);