Main Page   Class Hierarchy   Data Structures   File List   Data Fields   Globals  

xreal.C

Go to the documentation of this file.
00001 
00002 #include "stdinc.h"
00003 
00004 #ifndef TOOLBOX
00005 #ifdef USE_XREAL
00006 
00007 inline int xadd(unsigned long long &a, unsigned long long b)
00008 {
00009     a += b;
00010     return (a < b ? 1 : 0);     // a < b ==> overflow
00011 }
00012 
00013 inline int xsub(unsigned long long &a, unsigned long long b)
00014 {
00015     unsigned long long aa = a;
00016     a -= b;
00017     return (a > aa ? 1 : 0);    // a > aa ==> underflow
00018 }
00019 
00020 // Constructors:
00021 
00022 xreal::xreal() {i = f = 0;}                                     // default
00023 
00024 //xreal::xreal(xreal x) {                                       // x = xreal
00025 //    i = x.i;
00026 //    f = x.f;
00027 //}
00028 
00029 xreal::xreal(long long ii, unsigned long long ff) {
00030     i = ii;
00031     f = ff;
00032 }
00033 
00034 xreal::xreal(int ii) {                                          // x = int
00035     i = ii;
00036     f = 0;
00037 }
00038 
00039 xreal::xreal(real x)                                            // x = real
00040 {
00041     real ii = floor(x);                 // split integer/fraction
00042     real ff = x - ii;
00043 
00044     // Check for over/underflow.
00045 
00046     if (ii <= -TWO63) {                 // comparison with TWO63N
00047                                         // here fails!
00048 
00049         // i = TWO63N;                  // does not work on Linux:
00050                                         // RHS is interpreted as int
00051 
00052         // * Ugly! *
00053 
00054         i = 1;
00055         i = i<<63;                      // should work (overflow/wrap)...
00056 
00057         f = 0;                          // smallest possible xreal
00058 
00059     } else if (ii >= TWO63) {
00060 
00061         // i = TWO63M;                  // does not work on linux:
00062                                         // RHS is interpreted as int
00063 
00064         // * Ugly! *
00065 
00066         i = 1;
00067         i = i <<63;
00068         i--;                            // should work (overflow/wrap)...
00069 
00070         f = 0; f--;                     // largest possible xreal
00071 
00072     } else {
00073         i = (long long)ii;
00074         f = (unsigned long long)(TWO64*ff);
00075     }
00076 }
00077 
00078 real xreal::to_real()
00079 {
00080     // Explicitly avoid obvious roundoff problems near zero.
00081 
00082     if (i == -1) {
00083 
00084         return -((0-f)*TWO64I); // TWO64 <--> 0!
00085                 
00086     } else
00087         return i + f*TWO64I;    // should be OK for other real values
00088 }
00089 
00090 // Unary -, binary +, -, +=, -= (don't check for over/underflow):
00091 
00092 xreal xreal::operator - () {return xreal(-i-1, 0-f);}
00093 
00094 xreal xreal::operator + (const xreal y) {
00095     unsigned long long sumf = f;
00096     long long sumi = i + y.i + xadd(sumf, y.f);
00097     return xreal(sumi, sumf);
00098 }
00099 
00100 xreal xreal::operator - (const xreal y) {
00101     unsigned long long sumf = f;
00102     long long sumi = i - y.i - xsub(sumf, y.f);
00103     return xreal(sumi, sumf);
00104 }
00105 
00106 xreal& xreal::operator += (const xreal y) {
00107     i += y.i + xadd(f, y.f);
00108     return *this;
00109 }
00110 
00111 xreal& xreal::operator -= (const xreal y) {
00112     i -= y.i + xsub(f, y.f);
00113     return *this;
00114 }
00115 xreal xreal::operator + (const real y) {
00116     return *this + (xreal)y;
00117 }
00118 
00119 xreal xreal::operator - (const real y) {
00120     return *this - (xreal)y;
00121 }
00122 
00123 xreal& xreal::operator += (const real y) {
00124     *this += (xreal)y;
00125     return *this;
00126 }
00127 
00128 xreal& xreal::operator -= (const real y) {
00129     *this -= (xreal)y;
00130     return *this;
00131 }
00132 
00133 // Logical xreal operators ==, !=, <, <=, >, >=:
00134 
00135 bool xreal::operator == (const xreal y) {
00136     return (i == y.i && f == y.f);
00137 }
00138 
00139 bool xreal::operator != (const xreal y) {
00140     return (i != y.i || f != y.f);
00141 }
00142 
00143 bool xreal::operator < (const xreal y) {
00144     return (i < y.i || (i == y.i && f < y.f));
00145 }
00146 
00147 bool xreal::operator <= (const xreal y) {
00148     return (i < y.i || (i == y.i && f <= y.f));
00149 }
00150 
00151 bool xreal::operator > (const xreal y) {
00152     return (i > y.i || (i == y.i && f > y.f));
00153 }
00154 
00155 bool xreal::operator >= (const xreal y) {
00156     return (i > y.i || (i == y.i && f >= y.f));
00157 }
00158 
00159 real fmod2(xreal x, real y)     // assumes y is a power of 2 less than 1
00160 {
00161     return fmod(x.get_frac(), y);
00162 }
00163 
00164 #else
00165 
00166 real fmod2(xreal x, real y)
00167 {
00168     return fmod(x, y);
00169 }
00170 
00171 #endif
00172 
00173 void xprint(xreal x,
00174             ostream & s,        // default = cerr
00175             bool newline)       // default = true
00176 {
00177 #ifdef USE_XREAL
00178     s << x.get_i() << "+" << x.get_f();
00179 #else
00180     s << x;
00181 #endif
00182     if (newline) s << endl;
00183 }
00184 
00185 #else
00186 
00187 main()
00188 {
00189     cerr.precision(HIGH_PRECISION);
00190 
00191     xreal x = 2000+M_PI, y, z;
00192     PRC(x); x.print(); cerr << endl;
00193 
00194     z = (y = x + 1);
00195     PRC(y); y.print(); cerr << endl;
00196     PRC(z); z.print(); cerr << endl;
00197 
00198     real dx = 1.e-16;
00199     y = x + dx;
00200     PRC(y); y.print(); cerr << endl;
00201 
00202     real dy = y - x;
00203     PRL(dy);
00204 }
00205 
00206 #endif

Generated at Sun Feb 24 09:57:21 2002 for STARLAB by doxygen1.2.6 written by Dimitri van Heesch, © 1997-2001