File indexing completed on 2025-02-24 09:58:49
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_NUMERIC_INTERVAL_ROUNDED_ARITH_HPP
0011 #define BOOST_NUMERIC_INTERVAL_ROUNDED_ARITH_HPP
0012
0013 #include <boost/numeric/interval/rounding.hpp>
0014 #include <boost/numeric/interval/detail/bugs.hpp>
0015 #include <boost/config/no_tr1/cmath.hpp>
0016
0017 namespace boost {
0018 namespace numeric {
0019 namespace interval_lib {
0020
0021
0022
0023
0024
0025
0026 template<class T, class Rounding>
0027 struct rounded_arith_exact: Rounding {
0028 void init() { }
0029 template<class U> T conv_down(U const &v) { return v; }
0030 template<class U> T conv_up (U const &v) { return v; }
0031 T add_down (const T& x, const T& y) { return x + y; }
0032 T add_up (const T& x, const T& y) { return x + y; }
0033 T sub_down (const T& x, const T& y) { return x - y; }
0034 T sub_up (const T& x, const T& y) { return x - y; }
0035 T mul_down (const T& x, const T& y) { return x * y; }
0036 T mul_up (const T& x, const T& y) { return x * y; }
0037 T div_down (const T& x, const T& y) { return x / y; }
0038 T div_up (const T& x, const T& y) { return x / y; }
0039 T median (const T& x, const T& y) { return (x + y) / 2; }
0040 T sqrt_down(const T& x)
0041 { BOOST_NUMERIC_INTERVAL_using_math(sqrt); return sqrt(x); }
0042 T sqrt_up (const T& x)
0043 { BOOST_NUMERIC_INTERVAL_using_math(sqrt); return sqrt(x); }
0044 T int_down (const T& x)
0045 { BOOST_NUMERIC_INTERVAL_using_math(floor); return floor(x); }
0046 T int_up (const T& x)
0047 { BOOST_NUMERIC_INTERVAL_using_math(ceil); return ceil(x); }
0048 };
0049
0050 template<class T, class Rounding>
0051 struct rounded_arith_std: Rounding {
0052 # define BOOST_DN(EXPR) this->downward(); return this->force_rounding(EXPR)
0053 # define BOOST_NR(EXPR) this->to_nearest(); return this->force_rounding(EXPR)
0054 # define BOOST_UP(EXPR) this->upward(); return this->force_rounding(EXPR)
0055 void init() { }
0056 template<class U> T conv_down(U const &v) { BOOST_DN(v); }
0057 template<class U> T conv_up (U const &v) { BOOST_UP(v); }
0058 T add_down(const T& x, const T& y) { BOOST_DN(x + y); }
0059 T sub_down(const T& x, const T& y) { BOOST_DN(x - y); }
0060 T mul_down(const T& x, const T& y) { BOOST_DN(x * y); }
0061 T div_down(const T& x, const T& y) { BOOST_DN(x / y); }
0062 T add_up (const T& x, const T& y) { BOOST_UP(x + y); }
0063 T sub_up (const T& x, const T& y) { BOOST_UP(x - y); }
0064 T mul_up (const T& x, const T& y) { BOOST_UP(x * y); }
0065 T div_up (const T& x, const T& y) { BOOST_UP(x / y); }
0066 T median(const T& x, const T& y) { BOOST_NR((x + y) / 2); }
0067 T sqrt_down(const T& x)
0068 { BOOST_NUMERIC_INTERVAL_using_math(sqrt); BOOST_DN(sqrt(x)); }
0069 T sqrt_up (const T& x)
0070 { BOOST_NUMERIC_INTERVAL_using_math(sqrt); BOOST_UP(sqrt(x)); }
0071 T int_down(const T& x) { this->downward(); return this->to_int(x); }
0072 T int_up (const T& x) { this->upward(); return this->to_int(x); }
0073 # undef BOOST_DN
0074 # undef BOOST_NR
0075 # undef BOOST_UP
0076 };
0077
0078 template<class T, class Rounding>
0079 struct rounded_arith_opp: Rounding {
0080 void init() { this->upward(); }
0081 # define BOOST_DN(EXPR) \
0082 this->downward(); \
0083 T r = this->force_rounding(EXPR); \
0084 this->upward(); \
0085 return r
0086 # define BOOST_NR(EXPR) \
0087 this->to_nearest(); \
0088 T r = this->force_rounding(EXPR); \
0089 this->upward(); \
0090 return r
0091 # define BOOST_UP(EXPR) return this->force_rounding(EXPR)
0092 # define BOOST_UP_NEG(EXPR) return -this->force_rounding(EXPR)
0093 template<class U> T conv_down(U const &v) { BOOST_UP_NEG(-v); }
0094 template<class U> T conv_up (U const &v) { BOOST_UP(v); }
0095 T add_down(const T& x, const T& y) { BOOST_UP_NEG((-x) - y); }
0096 T sub_down(const T& x, const T& y) { BOOST_UP_NEG(y - x); }
0097 T mul_down(const T& x, const T& y) { BOOST_UP_NEG(x * (-y)); }
0098 T div_down(const T& x, const T& y) { BOOST_UP_NEG(x / (-y)); }
0099 T add_up (const T& x, const T& y) { BOOST_UP(x + y); }
0100 T sub_up (const T& x, const T& y) { BOOST_UP(x - y); }
0101 T mul_up (const T& x, const T& y) { BOOST_UP(x * y); }
0102 T div_up (const T& x, const T& y) { BOOST_UP(x / y); }
0103 T median (const T& x, const T& y) { BOOST_NR((x + y) / 2); }
0104 T sqrt_down(const T& x)
0105 { BOOST_NUMERIC_INTERVAL_using_math(sqrt); BOOST_DN(sqrt(x)); }
0106 T sqrt_up (const T& x)
0107 { BOOST_NUMERIC_INTERVAL_using_math(sqrt); BOOST_UP(sqrt(x)); }
0108 T int_down(const T& x) { return -this->to_int(-x); }
0109 T int_up (const T& x) { return this->to_int(x); }
0110 # undef BOOST_DN
0111 # undef BOOST_NR
0112 # undef BOOST_UP
0113 # undef BOOST_UP_NEG
0114 };
0115
0116 }
0117 }
0118 }
0119
0120 #endif