|
Boost-Commit : |
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);
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