Warning, file /include/boost/numeric/interval/detail/division.hpp was not indexed
or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef BOOST_NUMERIC_INTERVAL_DETAIL_DIVISION_HPP
0011 #define BOOST_NUMERIC_INTERVAL_DETAIL_DIVISION_HPP
0012
0013 #include <boost/numeric/interval/detail/interval_prototype.hpp>
0014 #include <boost/numeric/interval/detail/bugs.hpp>
0015 #include <boost/numeric/interval/detail/test_input.hpp>
0016 #include <boost/numeric/interval/rounded_arith.hpp>
0017 #include <algorithm>
0018
0019 namespace boost {
0020 namespace numeric {
0021 namespace interval_lib {
0022 namespace detail {
0023
0024 template<class T, class Policies> inline
0025 interval<T, Policies> div_non_zero(const interval<T, Policies>& x,
0026 const interval<T, Policies>& y)
0027 {
0028
0029 typename Policies::rounding rnd;
0030 typedef interval<T, Policies> I;
0031 const T& xl = x.lower();
0032 const T& xu = x.upper();
0033 const T& yl = y.lower();
0034 const T& yu = y.upper();
0035 if (::boost::numeric::interval_lib::user::is_neg(xu))
0036 if (::boost::numeric::interval_lib::user::is_neg(yu))
0037 return I(rnd.div_down(xu, yl), rnd.div_up(xl, yu), true);
0038 else
0039 return I(rnd.div_down(xl, yl), rnd.div_up(xu, yu), true);
0040 else if (::boost::numeric::interval_lib::user::is_neg(xl))
0041 if (::boost::numeric::interval_lib::user::is_neg(yu))
0042 return I(rnd.div_down(xu, yu), rnd.div_up(xl, yu), true);
0043 else
0044 return I(rnd.div_down(xl, yl), rnd.div_up(xu, yl), true);
0045 else
0046 if (::boost::numeric::interval_lib::user::is_neg(yu))
0047 return I(rnd.div_down(xu, yu), rnd.div_up(xl, yl), true);
0048 else
0049 return I(rnd.div_down(xl, yu), rnd.div_up(xu, yl), true);
0050 }
0051
0052 template<class T, class Policies> inline
0053 interval<T, Policies> div_non_zero(const T& x, const interval<T, Policies>& y)
0054 {
0055
0056 typename Policies::rounding rnd;
0057 typedef interval<T, Policies> I;
0058 const T& yl = y.lower();
0059 const T& yu = y.upper();
0060 if (::boost::numeric::interval_lib::user::is_neg(x))
0061 return I(rnd.div_down(x, yl), rnd.div_up(x, yu), true);
0062 else
0063 return I(rnd.div_down(x, yu), rnd.div_up(x, yl), true);
0064 }
0065
0066 template<class T, class Policies> inline
0067 interval<T, Policies> div_positive(const interval<T, Policies>& x, const T& yu)
0068 {
0069
0070 if (::boost::numeric::interval_lib::user::is_zero(x.lower()) &&
0071 ::boost::numeric::interval_lib::user::is_zero(x.upper()))
0072 return x;
0073 typename Policies::rounding rnd;
0074 typedef interval<T, Policies> I;
0075 const T& xl = x.lower();
0076 const T& xu = x.upper();
0077 typedef typename Policies::checking checking;
0078 if (::boost::numeric::interval_lib::user::is_neg(xu))
0079 return I(checking::neg_inf(), rnd.div_up(xu, yu), true);
0080 else if (::boost::numeric::interval_lib::user::is_neg(xl))
0081 return I(checking::neg_inf(), checking::pos_inf(), true);
0082 else
0083 return I(rnd.div_down(xl, yu), checking::pos_inf(), true);
0084 }
0085
0086 template<class T, class Policies> inline
0087 interval<T, Policies> div_positive(const T& x, const T& yu)
0088 {
0089
0090 typedef interval<T, Policies> I;
0091 if (::boost::numeric::interval_lib::user::is_zero(x))
0092 return I(static_cast<T>(0), static_cast<T>(0), true);
0093 typename Policies::rounding rnd;
0094 typedef typename Policies::checking checking;
0095 if (::boost::numeric::interval_lib::user::is_neg(x))
0096 return I(checking::neg_inf(), rnd.div_up(x, yu), true);
0097 else
0098 return I(rnd.div_down(x, yu), checking::pos_inf(), true);
0099 }
0100
0101 template<class T, class Policies> inline
0102 interval<T, Policies> div_negative(const interval<T, Policies>& x, const T& yl)
0103 {
0104
0105 if (::boost::numeric::interval_lib::user::is_zero(x.lower()) &&
0106 ::boost::numeric::interval_lib::user::is_zero(x.upper()))
0107 return x;
0108 typename Policies::rounding rnd;
0109 typedef interval<T, Policies> I;
0110 const T& xl = x.lower();
0111 const T& xu = x.upper();
0112 typedef typename Policies::checking checking;
0113 if (::boost::numeric::interval_lib::user::is_neg(xu))
0114 return I(rnd.div_down(xu, yl), checking::pos_inf(), true);
0115 else if (::boost::numeric::interval_lib::user::is_neg(xl))
0116 return I(checking::neg_inf(), checking::pos_inf(), true);
0117 else
0118 return I(checking::neg_inf(), rnd.div_up(xl, yl), true);
0119 }
0120
0121 template<class T, class Policies> inline
0122 interval<T, Policies> div_negative(const T& x, const T& yl)
0123 {
0124
0125 typedef interval<T, Policies> I;
0126 if (::boost::numeric::interval_lib::user::is_zero(x))
0127 return I(static_cast<T>(0), static_cast<T>(0), true);
0128 typename Policies::rounding rnd;
0129 typedef typename Policies::checking checking;
0130 if (::boost::numeric::interval_lib::user::is_neg(x))
0131 return I(rnd.div_down(x, yl), checking::pos_inf(), true);
0132 else
0133 return I(checking::neg_inf(), rnd.div_up(x, yl), true);
0134 }
0135
0136 template<class T, class Policies> inline
0137 interval<T, Policies> div_zero(const interval<T, Policies>& x)
0138 {
0139 if (::boost::numeric::interval_lib::user::is_zero(x.lower()) &&
0140 ::boost::numeric::interval_lib::user::is_zero(x.upper()))
0141 return x;
0142 else return interval<T, Policies>::whole();
0143 }
0144
0145 template<class T, class Policies> inline
0146 interval<T, Policies> div_zero(const T& x)
0147 {
0148 if (::boost::numeric::interval_lib::user::is_zero(x))
0149 return interval<T, Policies>(static_cast<T>(0), static_cast<T>(0), true);
0150 else return interval<T, Policies>::whole();
0151 }
0152
0153 template<class T, class Policies> inline
0154 interval<T, Policies> div_zero_part1(const interval<T, Policies>& x,
0155 const interval<T, Policies>& y, bool& b)
0156 {
0157
0158 if (::boost::numeric::interval_lib::user::is_zero(x.lower()) && ::boost::numeric::interval_lib::user::is_zero(x.upper()))
0159 { b = false; return x; }
0160 typename Policies::rounding rnd;
0161 typedef interval<T, Policies> I;
0162 const T& xl = x.lower();
0163 const T& xu = x.upper();
0164 const T& yl = y.lower();
0165 const T& yu = y.upper();
0166 typedef typename Policies::checking checking;
0167 if (::boost::numeric::interval_lib::user::is_neg(xu))
0168 { b = true; return I(checking::neg_inf(), rnd.div_up(xu, yu), true); }
0169 else if (::boost::numeric::interval_lib::user::is_neg(xl))
0170 { b = false; return I(checking::neg_inf(), checking::pos_inf(), true); }
0171 else
0172 { b = true; return I(checking::neg_inf(), rnd.div_up(xl, yl), true); }
0173 }
0174
0175 template<class T, class Policies> inline
0176 interval<T, Policies> div_zero_part2(const interval<T, Policies>& x,
0177 const interval<T, Policies>& y)
0178 {
0179
0180 typename Policies::rounding rnd;
0181 typedef interval<T, Policies> I;
0182 typedef typename Policies::checking checking;
0183 if (::boost::numeric::interval_lib::user::is_neg(x.upper()))
0184 return I(rnd.div_down(x.upper(), y.lower()), checking::pos_inf(), true);
0185 else
0186 return I(rnd.div_down(x.lower(), y.upper()), checking::pos_inf(), true);
0187 }
0188
0189 }
0190 }
0191 }
0192 }
0193
0194 #endif