C-XSC - A C++ Class Library for Extended Scientific Computing
2.5.4
|
00001 /* 00002 ** CXSC is a C++ library for eXtended Scientific Computing (V 2.5.4) 00003 ** 00004 ** Copyright (C) 1990-2000 Institut fuer Angewandte Mathematik, 00005 ** Universitaet Karlsruhe, Germany 00006 ** (C) 2000-2014 Wiss. Rechnen/Softwaretechnologie 00007 ** Universitaet Wuppertal, Germany 00008 ** 00009 ** This library is free software; you can redistribute it and/or 00010 ** modify it under the terms of the GNU Library General Public 00011 ** License as published by the Free Software Foundation; either 00012 ** version 2 of the License, or (at your option) any later version. 00013 ** 00014 ** This library is distributed in the hope that it will be useful, 00015 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 ** Library General Public License for more details. 00018 ** 00019 ** You should have received a copy of the GNU Library General Public 00020 ** License along with this library; if not, write to the Free 00021 ** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 */ 00023 00024 /* CVS $Id: lx_real.inl,v 1.8 2014/01/30 17:23:47 cxsc Exp $ */ 00025 00026 /* 00027 ** F. Blomquist, University of Wuppertal, 19.09.2007; 00028 */ 00029 00030 namespace cxsc { 00031 00032 // -------------------------------------------------------------------------- 00033 // -------------------------------------------------------------------------- 00034 // --------- Inline functions and operators related to type lx_real --------- 00035 // -------------------------------------------------------------------------- 00036 // -------------------------------------------------------------------------- 00037 00038 inline void times2pown(lx_real &a, const real &n) throw() 00039 { 00040 a = lx_real(add_real(n,a.ex),a.lr); 00041 } 00042 00043 inline std::string & operator << (std::string &s, const lx_real& a) 00044 throw() 00045 // The value of a variable a of type lx_real is copied to a string s. 00046 // s has the form: {2**(ex)*lr} 00047 { 00048 std::stringstream ss; 00049 string str; 00050 00051 str = "{2**("; 00052 s += str; 00053 ss << SaveOpt << SetPrecision(0,0) << Fixed << a.ex << RestoreOpt; 00054 ss >> str; 00055 s += str; 00056 s+=")*"; 00057 s << a.lr; 00058 s+='}'; 00059 return s; 00060 } 00061 00062 00063 inline bool Is_Integer(const real& x) 00064 // returns 1 if x is an integer value and 00065 // if |x| <= 2^53 - 1 = 9007199254740991.0; 00066 // otherwise 0 is returned 00067 { 00068 double dbl1,dbl2; 00069 dbl1 = _double(x); 00070 dbl2 = floor(dbl1); 00071 if (dbl1 == dbl2 && fabs(dbl1) <= Max_Int_R) return 1; 00072 else return 0; 00073 } 00074 00075 inline real add_real(const real &a, const real &b) throw() 00076 { 00077 real res(a+b); 00078 if (abs(res)>Max_Int_R) 00079 cxscthrow(REAL_INT_OUT_OF_RANGE( 00080 "add_real(const real&, const real&)")); 00081 return res; 00082 } 00083 00084 inline real sub_real(const real &a, const real &b) throw() 00085 { 00086 real res(a-b); 00087 if (abs(res)>Max_Int_R) 00088 cxscthrow(REAL_INT_OUT_OF_RANGE("sub_real(const real&, const real&)")); 00089 return res; 00090 } 00091 00092 inline int StagPrec(const lx_real &a) throw() 00093 { return StagPrec(a.lr); } 00094 00095 inline real expo(const lx_real &a) throw() 00096 { return (a.ex); } 00097 00098 inline int sign(const lx_real &a) throw() 00099 { return sign(a.lr); } 00100 00101 inline l_real lr_part(const lx_real &a) throw() 00102 { return (a.lr); } 00103 00104 inline lx_real abs(const lx_real& a) throw() 00105 { return lx_real(a.ex,abs(a.lr)); } 00106 00107 inline lx_real adjust(const lx_real &a) throw() 00108 { return lx_real(a.ex,adjust(a.lr)); } 00109 00110 inline void times2pown_neg(lx_real& a, const real& n) throw() 00111 // Calculating an approximation of a*2^n, n = 0,-1,-2,...,-9007199254740991.0; 00112 // n MUST be an integer and n MUST not be positive! 00113 // These conditions are not tested in this function! 00114 // Blomquist, 09.11.2008; 00115 { 00116 int exal(expo_gr(a.lr)); 00117 real exa,d,n_d; 00118 l_real lia(a.lr); 00119 // int k; 00120 00121 if (exal>-100000) // a != [0,0] 00122 { 00123 exa = a.ex; 00124 if (exa < -Max_Int_R - n) // exa+n < -9007199254740991; 00125 { // It holds: -Max_Int_R - n in {-Max_Int_R, ...,-1,0}, 00126 // Thus, -Max_Int_R - n is always in integer value. 00127 // Furthermore it holds: exa in {-Max_Int_R,...,-2,-1}. 00128 d = -Max_Int_R - exa; // d in {-Max_Int_R+1,..., -1,0} 00129 n_d = n-d; 00130 // With exa+n < -Max_Int_R and with exa+d = -Max_Int_R 00131 // it follows: n-d < 0, and: 00132 // n-d in {-Max_Int_R,-Max_Int_R+1, ... , -1}; 00133 // Thus, n-d is a negative and integer value. 00134 if (n_d < -2100) 00135 lia = 0.0; 00136 else // -2100 <= n_d <0: 00137 Times2pown(lia,n_d); 00138 a = lx_real(-Max_Int_R,lia); 00139 } 00140 else // n+a.ex >= -9007199254740991, so an integer overflow 00141 // is not possible here! 00142 a = lx_real(n+a.ex,lia); 00143 } 00144 } // times2pown_neg(...) 00145 00146 00147 inline lx_real & lx_real::operator = (const lx_real &a) throw() 00148 { 00149 ex = a.ex; 00150 lr = a.lr; 00151 return *this; 00152 } 00153 00154 inline lx_real & lx_real::operator = (const l_real &a) throw() 00155 { 00156 ex = 0; 00157 lr = a; 00158 return *this; 00159 } 00160 00161 inline lx_real & lx_real::operator = (const real &a) throw() 00162 { 00163 ex = 0; 00164 lr = a; 00165 return *this; 00166 } 00167 00168 // ----------------------------------------------------- 00169 00170 inline bool eq_zero(const lx_real &a) throw() 00171 { return (a.lr == 0 ); } 00172 00173 inline bool gr_zero(const lx_real &a) throw() 00174 { return (a.lr > 0 ); } 00175 00176 inline bool ge_zero(const lx_real &a) throw() 00177 { return (a.lr >= 0); } 00178 00179 inline bool sm_zero(const lx_real &a) throw() 00180 { return (a.lr < 0 ); } 00181 00182 inline bool se_zero(const lx_real &a) throw() 00183 { return (a.lr <= 0); } 00184 00185 // ----------------------------------------------------- 00186 00187 inline lx_real operator -(const lx_real &a) throw() 00188 { return lx_real(a.ex,-a.lr); } 00189 00190 inline lx_real operator +(const lx_real &a) throw() 00191 { return a; } 00192 00193 inline lx_real operator + (const lx_real& a, const l_real& b) throw() 00194 { return a + lx_real(b); } 00195 inline lx_real operator + (const l_real& a, const lx_real& b) throw() 00196 { return lx_real(a) + b; } 00197 inline lx_real operator + (const lx_real& a, const real& b) throw() 00198 { return a + lx_real(l_real(b)); } 00199 inline lx_real operator + (const real& a, const lx_real& b) throw() 00200 { return lx_real(l_real(a)) + b; } 00201 00202 inline lx_real & operator +=(lx_real& a, const lx_real& b) throw() 00203 { return a = a+b; } 00204 inline lx_real & operator +=(lx_real& a, const l_real& b) throw() 00205 { return a = a+b; } 00206 inline lx_real & operator +=(lx_real& a, const real& b) throw() 00207 { return a = a+b; } 00208 00209 inline lx_real operator - (const lx_real& a, const lx_real& b) throw() 00210 { return a + lx_real(-b); } 00211 inline lx_real operator - (const lx_real& a, const l_real& b) throw() 00212 { return a + lx_real(-b); } 00213 inline lx_real operator - (const l_real& a, const lx_real& b) throw() 00214 { return lx_real(a) + lx_real(-b); } 00215 inline lx_real operator - (const lx_real& a, const real& b) throw() 00216 { return a + lx_real(-b); } 00217 inline lx_real operator - (const real& a, const lx_real& b) throw() 00218 { return lx_real(a) + lx_real(-b); } 00219 00220 inline lx_real & operator -=(lx_real& a, const lx_real& b) throw() 00221 { return a = a-b; } 00222 inline lx_real & operator -=(lx_real& a, const l_real& b) throw() 00223 { return a = a-b; } 00224 inline lx_real & operator -=(lx_real& a, const real& b) throw() 00225 { return a = a-b; } 00226 00227 inline lx_real operator * (const lx_real& a, const l_real& b) throw() 00228 { return a * lx_real(b); } 00229 inline lx_real operator * (const l_real& a, const lx_real& b) throw() 00230 { return lx_real(a) * b; } 00231 inline lx_real operator * (const lx_real& a, const real& b) throw() 00232 { return a * lx_real(b); } 00233 inline lx_real operator * (const real& a, const lx_real& b) throw() 00234 { return lx_real(a) * b; } 00235 00236 inline lx_real & operator *=(lx_real& a, const lx_real& b) throw() 00237 { return a = a*b; } 00238 inline lx_real & operator *=(lx_real& a, const l_real& b) throw() 00239 { return a = a*b; } 00240 inline lx_real & operator *=(lx_real& a, const real& b) throw() 00241 { return a = a*b; } 00242 00243 inline lx_real operator / (const lx_real& a, const l_real& b) throw() 00244 { return a / lx_real(b); } 00245 inline lx_real operator / (const l_real& a, const lx_real& b) throw() 00246 { return lx_real(a) / b; } 00247 inline lx_real operator / (const lx_real& a, const real& b) throw() 00248 { return a / lx_real(b); } 00249 inline lx_real operator / (const real& a, const lx_real& b) throw() 00250 { return lx_real(a) / b; } 00251 00252 inline lx_real & operator /=(lx_real& a, const lx_real& b) throw() 00253 { return a = a/b; } 00254 inline lx_real & operator /=(lx_real& a, const l_real& b) throw() 00255 { return a = a/b; } 00256 inline lx_real & operator /=(lx_real& a, const real& b) throw() 00257 { return a = a/b; } 00258 00259 inline bool operator ! (const lx_real& a) throw() 00260 { return !a.lr; } 00261 00262 inline bool operator == (const lx_real &a, const l_real &b) throw() 00263 { return (a==lx_real(b)); } 00264 00265 inline bool operator == (const l_real &a, const lx_real &b) throw() 00266 { return (lx_real(a)==b); } 00267 00268 inline bool operator == (const lx_real &a, const real &b) throw() 00269 { return (a==lx_real(b)); } 00270 00271 inline bool operator == (const real &a, const lx_real &b) throw() 00272 { return (lx_real(a)==b); } 00273 00274 00275 inline bool operator != (const lx_real &a, const lx_real &b) throw() 00276 { return !(a==b); } 00277 00278 inline bool operator != (const lx_real &a, const l_real &b) throw() 00279 { return !(a==lx_real(b)); } 00280 00281 inline bool operator != (const l_real &a, const lx_real &b) throw() 00282 { return !(lx_real(a)==b); } 00283 00284 inline bool operator != (const lx_real &a, const real &b) throw() 00285 { return !(a==lx_real(b)); } 00286 00287 inline bool operator != (const real &a, const lx_real &b) throw() 00288 { return !(lx_real(a)==b); } 00289 00290 inline bool operator <= (const lx_real &a, const lx_real &b) throw() 00291 { return !(a>b); } 00292 00293 inline bool operator < (const lx_real &a, const lx_real &b) throw() 00294 { return (b>a); } 00295 00296 inline bool operator >= (const lx_real &a, const lx_real &b) throw() 00297 { return !(a<b); } 00298 00299 // --------------------------------------------------------- 00300 00301 inline bool operator > (const real &a, const lx_real &b) throw() 00302 { return lx_real(a)>b; } 00303 00304 inline bool operator <= (const real &a, const lx_real &b) throw() 00305 { return !(a>b); } 00306 00307 inline bool operator < (const real &a, const lx_real &b) throw() 00308 { return b>lx_real(a); } 00309 00310 inline bool operator >= (const real &a, const lx_real &b) throw() 00311 { return !(a<b); } 00312 00313 // --------------------------------------------------------- 00314 00315 inline bool operator > (const lx_real &a, const real &b) throw() 00316 { return a>lx_real(b); } 00317 00318 inline bool operator <= (const lx_real &a, const real &b) throw() 00319 { return !(a>b); } 00320 00321 inline bool operator < (const lx_real &a, const real &b) throw() 00322 { return b>a; } 00323 00324 inline bool operator >= (const lx_real &a, const real &b) throw() 00325 { return !(a<b); } 00326 00327 // --------------------------------------------------------- 00328 00329 inline bool operator > (const l_real &a, const lx_real &b) throw() 00330 { return lx_real(a)>b; } 00331 00332 inline bool operator <= (const l_real &a, const lx_real &b) throw() 00333 { return !(a>b); } 00334 00335 inline bool operator < (const l_real &a, const lx_real &b) throw() 00336 { return b>lx_real(a); } 00337 00338 inline bool operator >= (const l_real &a, const lx_real &b) throw() 00339 { return !(a<b); } 00340 00341 // --------------------------------------------------------- 00342 00343 inline bool operator > (const lx_real &a, const l_real &b) throw() 00344 { return a>lx_real(b); } 00345 00346 inline bool operator <= (const lx_real &a, const l_real &b) throw() 00347 { return !(a>b); } 00348 00349 inline bool operator < (const lx_real &a, const l_real &b) throw() 00350 { return b>a; } 00351 00352 inline bool operator >= (const lx_real &a, const l_real &b) throw() 00353 { return !(a<b); } 00354 00355 // ----------------------------------------------------- 00356 00357 00358 inline lx_real max(const lx_real& a, const lx_real& b) 00359 { return (b>a)? b : a; } 00360 00361 inline lx_real min(const lx_real& a, const lx_real& b) 00362 { return (b>a)? a : b; } 00363 00364 inline real cutint(const real& x) throw() 00365 // y = cutint(x) delivers the truncated part y of x. 00366 // If y is not an integer value then 9007199254740992.0 00367 // is returned; 00368 // For all integer values y it holds: 00369 // |y| <= Max_Int_R := 9007199254740991.0 00370 // Examples: 00371 // y = cutint(-0.1); ---> y = 0; 00372 // y = cutint(-123.5); ---> y = -123.0; 00373 // y = cutint(+123.5); ---> y = +123.0; 00374 // y = cutint(9007199254740991.8); ---> y = 9007199254740992.0; 00375 // y = cutint(9007199254740992.0); ---> y = 9007199254740992.0; 00376 // y = cutint(-1e20); ---> y = 9007199254740992.0; 00377 // Blomquist, 26.05.2008; 00378 { 00379 real res(x); 00380 double dbl; 00381 bool neg; 00382 neg = x<0; 00383 if (neg) res = -res; // res = |x| 00384 if (res>Max_Int_R) res = 9007199254740992.0; 00385 else 00386 { 00387 dbl = _double(res); 00388 dbl = floor(dbl); 00389 res = real(dbl); 00390 if (neg) res = -res; 00391 } 00392 return res; 00393 } 00394 00395 } // end namespace cxsc