Developer documentation

rounding_mode.hpp
Go to the documentation of this file.
1 /********************************************************************
2  * This file is part of the source code of the realroot library.
3  * Author(s): J.P. Pavone, GALAAD, INRIA
4  * $Id: fpu.h,v 1.1 2005/07/11 09:15:23 mourrain Exp $
5  ********************************************************************/
6 #ifndef mmx_numerics_rounding_mode_hpp
7 #define mmx_numerics_rounding_mode_hpp
8 //--------------------------------------------------------------------
9 
10 //for c99 compilers
11 #ifndef _MSC_VER
12 #include <fenv.h>
13 
14 
15 
16 //--------------------------------------------------------------------
17 namespace mmx {
18 //--------------------------------------------------------------------
19 namespace numerics
20 {
21  inline int get_cw() { return fegetround(); };
22  inline int get_rnd() { return fegetround(); };
23  inline void set_cw( int cw ) { fesetround(cw);};
24  inline static int rnd_up() { return FE_UPWARD;};
25  inline static int rnd_dw() { return FE_DOWNWARD;};
26  inline static int rnd_nr() { return FE_TONEAREST;};
27  inline static int rnd_z() { return FE_TOWARDZERO;};
28  template< typename T > struct LongVersion { typedef T result_t; };
29  template<> struct LongVersion<float> { typedef long double result_t; };
30  template<> struct LongVersion<double> { typedef long double result_t; };
31  template< class T > struct fpu_rounding {
32  static const int id = 0;
33  typedef int rnd_t;
34  inline static rnd_t getrnd() { return 0; };
35  inline static void setrnd( rnd_t r ) { };
36  inline static int rnd_up() { return 0; };
37  inline static int rnd_dw() { return 0; };
38  inline static int rnd_nr() { return 0; };
39  inline static int rnd_z() { return 0; };
40  fpu_rounding( int ){};
41  };
42  template<> struct fpu_rounding<long double>
43  {
44  typedef int rnd_t;
45  inline static rnd_t getrnd() { return fegetround(); };
46  inline static void setrnd( rnd_t r ) { fesetround(r); };
47  inline static int rnd_up() { return FE_UPWARD;};
48  inline static int rnd_dw() { return FE_DOWNWARD;};
49  inline static int rnd_nr() { return FE_TONEAREST;};
50  inline static int rnd_z() { return FE_TOWARDZERO;};
51  static const int id = 1;
52  rnd_t m_prev;
53  bool m_chg;
54  fpu_rounding( rnd_t rnd )
55  {
56  m_chg = false;
57  m_prev = getrnd();
58  if ( m_prev != rnd )
59  {
60  m_chg = true;
61  setrnd(rnd);
62  };
63  };
65  if ( m_chg ) setrnd(m_prev);
66  };
67  };
68 
69 
70  template< typename T >
71  struct rounding : fpu_rounding< typename LongVersion< T >::result_t >
73 
74  template< typename T > inline T div_dw(const T& a, const T& b) { rounding<T> r(rounding<T>::rnd_dw()); return a/b; };
75  template< typename T > inline T div_up(const T& a, const T& b) { rounding<T> r(rounding<T>::rnd_up()); return a/b; };
76  template< typename T > inline T add_dw(const T& a, const T& b) { rounding<T> r(rounding<T>::rnd_dw()); return a+b; };
77  template< typename T > inline T add_up(const T& a, const T& b) { rounding<T> r(rounding<T>::rnd_up()); return a+b; };
78  template< typename T > inline T mul_dw(const T& a, const T& b) { rounding<T> r(rounding<T>::rnd_dw()); return a*b; };
79  template< typename T > inline T mul_up(const T& a, const T& b) { rounding<T> r(rounding<T>::rnd_up()); return a*b; };
80  template< typename T > inline T sub_dw(const T& a, const T& b) { rounding<T> r(rounding<T>::rnd_dw()); return a-b; };
81  template< typename T > inline T sub_up(const T& a, const T& b) { rounding<T> r(rounding<T>::rnd_up()); return a-b; };
82 
83  namespace rdw
84  {
85  template< typename T > inline
86  T upadd( const T& a, const T& b ) { T tmp = -a; tmp -= b; return -tmp; };
87  template< typename T > inline
88  T dwadd( const T& a, const T& b ) { return a+b; };
89  template< typename T > inline
90  T upsub( const T& a, const T& b ) { T tmp = b; tmp -= a; return -tmp; };
91  template< typename T > inline
92  T dwsub( const T& a, const T& b ) { return a-b; };
93  template< typename T > inline
94  T upmul( const T& a, const T& b ) { T tmp = -a; tmp *= b; return -tmp; };
95  template< typename T > inline
96  T dwmul( const T& a, const T& b ) { return a*b; };
97  template< typename T > inline
98  T updiv( const T& a, const T& b ) { T tmp = -a; tmp /= b; return -tmp; };
99  template< typename T > inline
100  T dwdiv( const T& a, const T& b ) { return a/b; };
101  template< typename T > inline
102  T updet( const T& a, const T& b, const T& c, const T& d )
103  { return upsub(upmul(a,d),dwmul(b,c)); };
104  template< typename T > inline
105  T dwdet( const T& a, const T& b, const T& c, const T& d )
106  { return dwsub(dwmul(a,d),upmul(b,c)); };
107  };
108 
109  namespace rup
110  {
111  template< typename T > inline
112  T upadd( const T& a, const T& b ) { return a+b; };
113  template< typename T > inline
114  T dwadd( const T& a, const T& b ) { T tmp = -a; tmp -= b; return -tmp; };
115  template< typename T > inline
116  T upsub( const T& a, const T& b ) { return a-b; };
117  template< typename T > inline
118  T dwsub( const T& a, const T& b ) { T tmp = b; tmp -= a; return -tmp; };
119  template< typename T > inline
120  T upmul( const T& a, const T& b ) { return a*b; };
121  template< typename T > inline
122  T dwmul( const T& a, const T& b ) { T tmp = -a; tmp *= b; return -tmp; };
123  template< typename T > inline
124  T updiv( const T& a, const T& b ) { return a/b; };
125  template< typename T > inline
126  T dwdiv( const T& a, const T& b ) { T tmp = -a; tmp /= b; return -tmp; };
127  template< typename T > inline
128  T updet( const T& a, const T& b, const T& c, const T& d )
129  { return upsub(upmul(a,d),dwmul(b,c)); };
130  template< typename T > inline
131  T dwdet( const T& a, const T& b, const T& c, const T& d )
132  { return dwsub(dwmul(a,d),upmul(b,c)); };
133  }
134 }; //namespace numerics
135 //======================================================================
136 } //namespace mmx
137 //======================================================================
138 #endif //end of definition for C99 compiler
139 
140 #ifdef _MSC_VER
141 #include <float.h>
142 
143 //copy round mode implementation of C99 compiler, using new definitions for Visual Studio compiler.
144  //--------------------------------------------------------------------
145  namespace mmx {
146  //--------------------------------------------------------------------
147  namespace numerics
148  {
149  inline int get_cw() {return _controlfp(0, 0); };
150  inline int get_rnd() {return _controlfp(0, 0); };
151  inline void set_cw( int cw ) { _controlfp(cw, _MCW_RC);};
152  inline static int rnd_up() { return _RC_UP;};
153  inline static int rnd_dw() { return _RC_DOWN;};
154  inline static int rnd_nr() { return _RC_NEAR;};
155  inline static int rnd_z() { return _RC_CHOP;};
156  template< typename T > struct LongVersion { typedef T result_t; };
157  template<> struct LongVersion<float> { typedef long double result_t; };
158  template<> struct LongVersion<double> { typedef long double result_t; };
159  template< class T > struct fpu_rounding {
160  static const int id = 0;
161  typedef int rnd_t;
162  inline static rnd_t getrnd() { return 0; };
163  inline static void setrnd( rnd_t r ) { };
164  inline static int rnd_up() { return 0; };
165  inline static int rnd_dw() { return 0; };
166  inline static int rnd_nr() { return 0; };
167  inline static int rnd_z() { return 0; };
168  fpu_rounding( int ){};
169  };
170  template<> struct fpu_rounding<long double>
171  {
172  typedef int rnd_t;
173  inline static rnd_t getrnd() { return _controlfp(0, 0); };
174  inline static void setrnd( rnd_t r ) { _controlfp(r, _MCW_RC); };
175  inline static int rnd_up() { return _RC_UP;};
176  inline static int rnd_dw() { return _RC_DOWN;};
177  inline static int rnd_nr() { return _RC_NEAR;};
178  inline static int rnd_z() { return _RC_CHOP;};
179  static const int id = 1;
180  rnd_t m_prev;
181  bool m_chg;
182  fpu_rounding( rnd_t rnd )
183  {
184  m_chg = false;
185  m_prev = getrnd();
186  if ( m_prev != rnd )
187  {
188  m_chg = true;
189  setrnd(rnd);
190  };
191  };
192  ~fpu_rounding() {
193  if ( m_chg ) setrnd(m_prev);
194  };
195  };
196 
197 
198  template< typename T >
199  struct rounding : fpu_rounding< typename LongVersion< T >::result_t >
200  { rounding( typename fpu_rounding<typename LongVersion<T>::result_t >::rnd_t rnd ) : fpu_rounding< typename LongVersion< T >::result_t >( rnd ) {}; };
201 
202  template< typename T > inline T div_dw(const T& a, const T& b) { rounding<T> r(rounding<T>::rnd_dw()); return a/b; };
203  template< typename T > inline T div_up(const T& a, const T& b) { rounding<T> r(rounding<T>::rnd_up()); return a/b; };
204  template< typename T > inline T add_dw(const T& a, const T& b) { rounding<T> r(rounding<T>::rnd_dw()); return a+b; };
205  template< typename T > inline T add_up(const T& a, const T& b) { rounding<T> r(rounding<T>::rnd_up()); return a+b; };
206  template< typename T > inline T mul_dw(const T& a, const T& b) { rounding<T> r(rounding<T>::rnd_dw()); return a*b; };
207  template< typename T > inline T mul_up(const T& a, const T& b) { rounding<T> r(rounding<T>::rnd_up()); return a*b; };
208  template< typename T > inline T sub_dw(const T& a, const T& b) { rounding<T> r(rounding<T>::rnd_dw()); return a-b; };
209  template< typename T > inline T sub_up(const T& a, const T& b) { rounding<T> r(rounding<T>::rnd_up()); return a-b; };
210 
211  namespace rdw
212  {
213  template< typename T > inline
214  T upadd( const T& a, const T& b ) { T tmp = -a; tmp -= b; return -tmp; };
215  template< typename T > inline
216  T dwadd( const T& a, const T& b ) { return a+b; };
217  template< typename T > inline
218  T upsub( const T& a, const T& b ) { T tmp = b; tmp -= a; return -tmp; };
219  template< typename T > inline
220  T dwsub( const T& a, const T& b ) { return a-b; };
221  template< typename T > inline
222  T upmul( const T& a, const T& b ) { T tmp = -a; tmp *= b; return -tmp; };
223  template< typename T > inline
224  T dwmul( const T& a, const T& b ) { return a*b; };
225  template< typename T > inline
226  T updiv( const T& a, const T& b ) { T tmp = -a; tmp /= b; return -tmp; };
227  template< typename T > inline
228  T dwdiv( const T& a, const T& b ) { return a/b; };
229  template< typename T > inline
230  T updet( const T& a, const T& b, const T& c, const T& d )
231  { return upsub(upmul(a,d),dwmul(b,c)); };
232  template< typename T > inline
233  T dwdet( const T& a, const T& b, const T& c, const T& d )
234  { return dwsub(dwmul(a,d),upmul(b,c)); };
235  };
236 
237  namespace rup
238  {
239  template< typename T > inline
240  T upadd( const T& a, const T& b ) { return a+b; };
241  template< typename T > inline
242  T dwadd( const T& a, const T& b ) { T tmp = -a; tmp -= b; return -tmp; };
243  template< typename T > inline
244  T upsub( const T& a, const T& b ) { return a-b; };
245  template< typename T > inline
246  T dwsub( const T& a, const T& b ) { T tmp = b; tmp -= a; return -tmp; };
247  template< typename T > inline
248  T upmul( const T& a, const T& b ) { return a*b; };
249  template< typename T > inline
250  T dwmul( const T& a, const T& b ) { T tmp = -a; tmp *= b; return -tmp; };
251  template< typename T > inline
252  T updiv( const T& a, const T& b ) { return a/b; };
253  template< typename T > inline
254  T dwdiv( const T& a, const T& b ) { T tmp = -a; tmp /= b; return -tmp; };
255  template< typename T > inline
256  T updet( const T& a, const T& b, const T& c, const T& d )
257  { return upsub(upmul(a,d),dwmul(b,c)); };
258  template< typename T > inline
259  T dwdet( const T& a, const T& b, const T& c, const T& d )
260  { return dwsub(dwmul(a,d),upmul(b,c)); };
261  }
262  }; //namespace numerics
263  //======================================================================
264  } //namespace mmx
265  //======================================================================
266 
267 #endif //end of definition for Visual Studio compiler
268 
269 #endif //end of rounding_mode definition
T dwmul(const T &a, const T &b)
Definition: rounding_mode.hpp:96
static int rnd_z()
Definition: rounding_mode.hpp:39
static int rnd_z()
Definition: rounding_mode.hpp:50
T upadd(const T &a, const T &b)
Definition: rounding_mode.hpp:86
const C & b
Definition: Interval_glue.hpp:25
T mul_up(const T &a, const T &b)
Definition: rounding_mode.hpp:79
static rnd_t getrnd()
Definition: rounding_mode.hpp:45
static int rnd_dw()
Definition: rounding_mode.hpp:37
static void setrnd(rnd_t r)
Definition: rounding_mode.hpp:35
T upmul(const T &a, const T &b)
Definition: rounding_mode.hpp:120
Definition: rounding_mode.hpp:28
static int rnd_dw()
Definition: rounding_mode.hpp:48
~fpu_rounding()
Definition: rounding_mode.hpp:64
T dwdet(const T &a, const T &b, const T &c, const T &d)
Definition: rounding_mode.hpp:105
long double result_t
Definition: rounding_mode.hpp:29
static void setrnd(rnd_t r)
Definition: rounding_mode.hpp:46
T result_t
Definition: rounding_mode.hpp:28
T sub_up(const T &a, const T &b)
Definition: rounding_mode.hpp:81
T dwadd(const T &a, const T &b)
Definition: rounding_mode.hpp:88
T upmul(const T &a, const T &b)
Definition: rounding_mode.hpp:94
int rnd_t
Definition: rounding_mode.hpp:44
T updet(const T &a, const T &b, const T &c, const T &d)
Definition: rounding_mode.hpp:128
int get_rnd()
Definition: rounding_mode.hpp:22
T div_up(const T &a, const T &b)
Definition: rounding_mode.hpp:75
void set_cw(int cw)
Definition: rounding_mode.hpp:23
Definition: rounding_mode.hpp:71
T upsub(const T &a, const T &b)
Definition: rounding_mode.hpp:116
T div_dw(const T &a, const T &b)
Definition: rounding_mode.hpp:74
static rnd_t getrnd()
Definition: rounding_mode.hpp:34
int get_cw()
Definition: rounding_mode.hpp:21
rounding(typename fpu_rounding< typename LongVersion< T >::result_t >::rnd_t rnd)
Definition: rounding_mode.hpp:72
T updiv(const T &a, const T &b)
Definition: rounding_mode.hpp:98
T dwdiv(const T &a, const T &b)
Definition: rounding_mode.hpp:100
T dwmul(const T &a, const T &b)
Definition: rounding_mode.hpp:122
T dwsub(const T &a, const T &b)
Definition: rounding_mode.hpp:92
Definition: rounding_mode.hpp:31
T dwsub(const T &a, const T &b)
Definition: rounding_mode.hpp:118
T dwdiv(const T &a, const T &b)
Definition: rounding_mode.hpp:126
static int rnd_up()
Definition: rounding_mode.hpp:47
static int rnd_up()
Definition: rounding_mode.hpp:36
T upadd(const T &a, const T &b)
Definition: rounding_mode.hpp:112
static int rnd_nr()
Definition: rounding_mode.hpp:38
T upsub(const T &a, const T &b)
Definition: rounding_mode.hpp:90
const C & c
Definition: Interval_glue.hpp:45
T add_up(const T &a, const T &b)
Definition: rounding_mode.hpp:77
rnd_t m_prev
Definition: rounding_mode.hpp:52
T sub_dw(const T &a, const T &b)
Definition: rounding_mode.hpp:80
T updet(const T &a, const T &b, const T &c, const T &d)
Definition: rounding_mode.hpp:102
T mul_dw(const T &a, const T &b)
Definition: rounding_mode.hpp:78
int rnd_t
Definition: rounding_mode.hpp:33
static int rnd_nr()
Definition: rounding_mode.hpp:49
T updiv(const T &a, const T &b)
Definition: rounding_mode.hpp:124
long double result_t
Definition: rounding_mode.hpp:30
T add_dw(const T &a, const T &b)
Definition: rounding_mode.hpp:76
Definition: array.hpp:12
fpu_rounding(rnd_t rnd)
Definition: rounding_mode.hpp:54
fpu_rounding(int)
Definition: rounding_mode.hpp:40
T dwdet(const T &a, const T &b, const T &c, const T &d)
Definition: rounding_mode.hpp:131
T dwadd(const T &a, const T &b)
Definition: rounding_mode.hpp:114
bool m_chg
Definition: rounding_mode.hpp:53
Home