C-XSC - A C++ Class Library for Extended Scientific Computing  2.5.4
lx_real.inl
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