|
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