Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-24 09:58:49

0001 /* Boost interval/rounded_arith.hpp template implementation file
0002  *
0003  * Copyright 2002-2003 Hervé Brönnimann, Guillaume Melquiond, Sylvain Pion
0004  *
0005  * Distributed under the Boost Software License, Version 1.0.
0006  * (See accompanying file LICENSE_1_0.txt or
0007  * copy at http://www.boost.org/LICENSE_1_0.txt)
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  * Three classes of rounding: exact, std, opp
0023  * See documentation for details.
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 } // namespace interval_lib
0117 } // namespace numeric
0118 } // namespace boost
0119 
0120 #endif // BOOST_NUMERIC_INTERVAL_ROUNDED_ARITH_HPP