Ereal.h

00001 /*  _________________________________________________________________________
00002  *
00003  *  UTILIB: A utility library for developing portable C++ codes.
00004  *  Copyright (c) 2001, Sandia National Laboratories.
00005  *  This software is distributed under the GNU Lesser General Public License.
00006  *  For more information, see the README file in the top UTILIB directory.
00007  *  _________________________________________________________________________
00008  */
00009 
00010 //
00011 // Ereal.h
00012 //
00020 #ifndef __Ereal_h
00021 #define __Ereal_h
00022 
00023 #ifdef NON_ANSI
00024 #include <iostream.h>
00025 #else
00026 #include <iostream>
00027 using namespace std;
00028 #endif
00029 #ifndef ANSI_HDRS
00030 #include <math.h>
00031 #include <ctype.h>
00032 #else
00033 #include <cmath>
00034 #include <cctype>
00035 #endif
00036 #include <values.h>
00037 #include "PackBuf.h"
00038 
00039 
00040 template <class Type> class Ereal;
00041 
00042 template <class Type> Ereal<Type>
00043 operator+ (const Ereal<Type>& x, const Ereal<Type>& y);
00044 
00045 template <class Type> Ereal<Type>
00046 operator+ (const Ereal<Type>& x, const Type y);
00047 
00048 template <class Type> Ereal<Type>
00049 operator+ (const Type x, const Ereal<Type>& y);
00050 
00051 template <class Type> Ereal<Type>
00052 operator- (const Ereal<Type>& x, const Ereal<Type>& y);
00053 
00054 template <class Type> Ereal<Type>
00055 operator- (const Ereal<Type>& x, const Type y);
00056 
00057 template <class Type> Ereal<Type>
00058 operator- (const Type x, const Ereal<Type>& y);
00059 
00060 template <class Type> Ereal<Type>
00061 operator* (const Ereal<Type>& x, const Ereal<Type>& y);
00062 
00063 template <class Type> Ereal<Type>
00064 operator* (const Ereal<Type>& x, const Type y);
00065 
00066 template <class Type> Ereal<Type>
00067 operator* (const Type x, const Ereal<Type>& y);
00068 
00069 template <class Type> Ereal<Type>
00070 operator/ (const Ereal<Type>& x, const Ereal<Type> y);
00071 
00072 template <class Type> Ereal<Type>
00073 operator/ (const Ereal<Type>& x, const Type y);
00074 
00075 template <class Type> Ereal<Type>
00076 operator/ (const Type x, const Ereal<Type>& y);
00077 
00078 template <class Type> Ereal<Type>
00079 operator+ (const Ereal<Type>& x);
00080 
00081 template <class Type> Ereal<Type> 
00082 operator- (const Ereal<Type>& num);
00083 
00084 template <class Type> bool
00085 operator== (const Ereal<Type>& x, const Ereal<Type>& y);
00086 
00087 template <class Type> bool
00088 operator== (const Ereal<Type>& x, const Type y);
00089 
00090 template <class Type> bool
00091 operator== (const Type x, const Ereal<Type>& y);
00092 
00093 template <class Type> bool
00094 operator!= (const Ereal<Type>& x, const Ereal<Type>& y);
00095 
00096 template <class Type> bool
00097 operator!= (const Ereal<Type>& x, const Type y);
00098 
00099 template <class Type> bool
00100 operator!= (const Type x, const Ereal<Type>& y);
00101 
00102 template <class Type> bool
00103 operator> (const Ereal<Type>& x, const Ereal<Type>& y);
00104 
00105 template <class Type> bool
00106 operator> (const Ereal<Type>& x, const Type y);
00107 
00108 template <class Type> bool
00109 operator> (const Type x, const Ereal<Type>& y);
00110 
00111 template <class Type> bool
00112 operator>= (const Ereal<Type>& x, const Ereal<Type>& y);
00113 
00114 template <class Type> bool
00115 operator>= (const Ereal<Type>& x, const Type y);
00116 
00117 template <class Type> bool
00118 operator>= (const Type x, const Ereal<Type>& y);
00119 
00120 template <class Type> bool
00121 operator< (const Ereal<Type>& x, const Ereal<Type>& y);
00122 
00123 template <class Type> bool
00124 operator< (const Ereal<Type>& x, const Type y);
00125 
00126 template <class Type> bool
00127 operator< (const Type x, const Ereal<Type>& y);
00128 
00129 template <class Type> bool
00130 operator<= (const Ereal<Type>& x, const Ereal<Type>& y);
00131 
00132 template <class Type> bool
00133 operator<= (const Ereal<Type>& x, const Type y);
00134 
00135 template <class Type> bool
00136 operator<= (const Type x, const Ereal<Type>& y);
00137 
00138 template <class Type>
00139 bool isinf(const Ereal<Type>& num);
00140 
00141 template <class Type>
00142 bool isnan(const Ereal<Type>& num);
00143 
00144 template <class Type>
00145 bool isind(const Ereal<Type>& num);
00146 
00147 template <class Type>
00148 bool finite(const Ereal<Type>& num);
00149 
00150 
00151 
00152 template <class Type>
00153 class Ereal
00154 {
00155 public:
00156 
00158   Ereal(const Type num=0.0);
00159 
00161   Ereal operator+= (const Ereal<Type>& num)
00162         {
00163         plus(val,Finite,num.val,num.Finite,val,Finite);
00164         return *this;
00165         }
00166 
00168   Ereal operator-= (const Ereal<Type>&)
00169         {
00170         minus(val,Finite,num.val,num.Finite,val,Finite);
00171         return *this;
00172         }
00173 
00175   Ereal operator*= (const Ereal<Type>&)
00176         {
00177         mult(val,Finite,num.val,num.Finite,val,Finite);
00178         return *this;
00179         }
00180 
00182   Ereal operator/= (const Ereal<Type>&)
00183         {
00184         div(val,Finite,num.val,num.Finite,val,Finite);
00185         return *this;
00186         }
00187 
00189   operator Type () const;
00190 
00191 #if defined(NON_ANSI) || defined(COUGAR) || defined(SGI) || defined(OSF)
00193   ostream& write(ostream& os) const;
00195   istream& read(istream& is);
00196 #else
00197 
00198   std::ostream& write(std::ostream& os) const;
00200   std::istream& read(std::istream& is);
00201 #endif
00202 
00203   PackBuffer& write(PackBuffer& os) const;
00205   UnPackBuffer& read(UnPackBuffer& is);
00206 
00207   friend Ereal<Type> operator+ <> (const Ereal<Type>& x, const Ereal<Type>& y);
00208 
00209   friend Ereal<Type> operator+ <> (const Ereal<Type>& x, const Type y);
00210 
00211   friend Ereal<Type> operator+ <> (const Type x, const Ereal<Type>& y);
00212 
00213   friend Ereal<Type> operator- <> (const Ereal<Type>& x, const Ereal<Type>& y);
00214 
00215   friend Ereal<Type> operator- <> (const Ereal<Type>& x, const Type y);
00216 
00217   friend Ereal<Type> operator- <> (const Type x, const Ereal<Type>& y);
00218 
00219   friend Ereal<Type> operator* <> (const Ereal<Type>& x, const Ereal<Type>& y);
00220 
00221   friend Ereal<Type> operator* <> (const Ereal<Type>& x, const Type y);
00222 
00223   friend Ereal<Type> operator* <> (const Type x, const Ereal<Type>& y);
00224 
00225   friend Ereal<Type> operator/ <> (const Ereal<Type>& x, const Ereal<Type> y);
00226 
00227   friend Ereal<Type> operator/ <> (const Ereal<Type>& x, const Type y);
00228 
00229   friend Ereal<Type> operator/ <> (const Type x, const Ereal<Type>& y);
00230 
00231   friend Ereal<Type> operator+ <> (const Ereal<Type>& x);
00232 
00233   friend Ereal<Type> operator- <> (const Ereal<Type>& num);
00234 
00235   friend bool operator== <> (const Type x, const Ereal<Type>& y);
00236 
00237   friend bool operator== <> (const Ereal<Type>&, const Ereal<Type>&);
00238 
00239   friend bool operator== <> (const Ereal<Type>&, const Type);
00240 
00241   friend bool operator< <> (const Ereal<Type>&, const Ereal<Type>&);
00242 
00243   friend bool operator< <> (const Ereal<Type>&, const Type);
00244 
00245   friend bool operator< <> (const Type x, const Ereal<Type>& y);
00246 
00247   friend bool operator<= <> (const Ereal<Type>&, const Ereal<Type>&);
00248 
00249   friend bool operator<= <> (const Ereal<Type>&, const Type);
00250 
00251   friend bool operator<= <> (const Type x, const Ereal<Type>& y);
00252 
00253   friend bool isinf<> (const Ereal<Type>& num);
00254 
00255   friend bool isnan<> (const Ereal<Type>& num);
00256 
00257   friend bool isind<> (const Ereal<Type>& num);
00258 
00259   friend bool finite<> (const Ereal<Type>& num);
00260 
00262   static Ereal<Type> positive_infinity;
00264   static Ereal<Type> negative_infinity;
00265 
00266 protected:
00267 
00269   Ereal(const Type num, const bool f_flag) : val(num), Finite(f_flag) {}
00271   Type val;
00273   bool Finite;
00274 
00276   static void plus(const Type xval, const bool xFinite, 
00277                 const Type yval, const bool yFinite, 
00278                 Type& rval, bool& rFinite);
00280   static void minus(const Type xval, const bool xFinite, 
00281                 const Type yval, const bool yFinite, 
00282                 Type& rval, bool& rFinite);
00284   static void mult(const Type xval, const bool xFinite, 
00285                 const Type yval, const bool yFinite, 
00286                 Type& rval, bool& rFinite);
00288   static void div(const Type xval, const bool xFinite, 
00289                 const Type yval, const bool yFinite, 
00290                 Type& rval, bool& rFinite);
00295   static void check_if_infinite(Type& val, bool& Finite);
00296 
00298   static Type positive_infinity_val;
00300   static Type negative_infinity_val;
00301 
00302 };
00303 
00304 
00305 template <class Type>
00306 Ereal<Type> Ereal<Type>::positive_infinity(1.0,false);
00307 
00308 
00309 template <class Type>
00310 Ereal<Type> Ereal<Type>::negative_infinity(-1.0,false);
00311 
00312 
00313 template <class Type>
00314 inline void Ereal<Type>::check_if_infinite(Type& val, bool& Finite)
00315 {
00316 if (Finite) {
00317    if (val <= negative_infinity_val) {
00318       Finite = false;
00319       val = -1.0;
00320       }
00321    else if (val >= positive_infinity_val) {
00322       Finite = false;
00323       val = 1.0;
00324       }
00325    }
00326 }
00327 
00328 
00329 template <class Type>
00330 inline Ereal<Type>::Ereal(const Type num)
00331 {
00332 val = num;
00333 Finite = true;
00334 check_if_infinite(val,Finite);
00335 }
00336 
00337 
00338 template <class Type>
00339 inline Ereal<Type>::operator Type () const
00340 {
00341 if (Finite) 
00342    return val;
00343 
00344 if (val == -1.0)
00345    return negative_infinity_val;
00346 else if (val == 1.0)
00347    return positive_infinity_val;
00348 else if (val == 2.0)
00349    return 0.0;                  // TODO: exception - NaN
00350 else 
00351    return 0.0;                  // TODO: exception - NaN
00352 }
00353 
00354 
00355 template <class Type> 
00356 inline void Ereal<Type>::plus(const Type xval, const bool xFinite, 
00357                         const Type yval, const bool yFinite, 
00358                         Type& rval, bool& rFinite)
00359 {
00360 if (xFinite) {
00361    if (yFinite) {
00362       rval = xval + yval;
00363       rFinite = true;
00364       check_if_infinite(rval,rFinite);
00365       }
00366    else {
00367       rFinite = false;
00368       rval = yval;
00369       }
00370    }
00371 
00372 else {
00373    rFinite = false;
00374    if (!yFinite) {
00375       if ((xval == 2.0) || (yval == 2.0))
00376          rval = 2.0;                            // NaN
00377       else if (xval*yval == 0.0)
00378          rval = 0.0;                            // Indeterminate
00379       else if (xval*yval == -1.0)
00380          rval = 0.0;                            // Indeterminate: infty - infty
00381       else
00382          rval = xval;
00383       }
00384    else
00385       rval = xval;
00386    }
00387 }
00388 
00389 
00390 template <class Type> 
00391 inline void Ereal<Type>::minus(const Type xval, const bool xFinite, 
00392                         const Type yval, const bool yFinite, 
00393                         Type& rval, bool& rFinite)
00394 {
00395 if (xFinite) {
00396    if (yFinite) {
00397       rval = xval - yval;
00398       rFinite = true;
00399       check_if_infinite(rval,rFinite);
00400       }
00401    else {
00402       rFinite = false;
00403       if (yval == 2.0)
00404          rval = 2.0;
00405       else
00406          rval = - yval;
00407       }
00408    }
00409 
00410 else {
00411    rFinite = false;
00412    if (!yFinite) {
00413       if ((xval == 2.0) || (yval == 2.0))
00414          rval = 2.0;                            // NaN
00415       else if (xval*yval == 0.0)
00416          rval = 0.0;                            // Indeterminate
00417       else if (xval*yval == 1.0)
00418          rval = 0.0;                            // Indeterminate: infty - infty
00419       else
00420          rval = xval;
00421       }
00422    else
00423       rval = xval;
00424    }
00425 }
00426 
00427 
00428 template <class Type> 
00429 inline void Ereal<Type>::mult(const Type xval, const bool xFinite, 
00430                         const Type yval, const bool yFinite, 
00431                         Type& rval, bool& rFinite)
00432 {
00433 if (xFinite) {
00434    if (yFinite) {
00435       rval = xval * yval;
00436       rFinite = true;
00437       check_if_infinite(rval,rFinite);
00438       }
00439    else {
00440       rFinite = false;
00441       if (yval == 2.0)
00442          rval = 2.0;
00443       else if (xval*yval == 0.0)                // Indeterminate: infty * 0
00444          rval = 0.0;                            //             OR Ind * num
00445       else if (xval*yval > 0.0)
00446          rval = 1.0;
00447       else 
00448          rval = -1.0;
00449       }
00450    }
00451 
00452 else {
00453    rFinite = false;
00454    if (yFinite) {
00455       if (xval == 2.0)
00456          rval = 2.0;
00457       else if (xval*yval == 0.0)                // Indeterminate: infty * 0
00458          rval = 0.0;                            //             OR Ind * num
00459       else if (xval*yval > 0.0)
00460          rval = 1.0;
00461       else 
00462          rval = -1.0;
00463       }
00464    else {
00465       if ((xval == 2.0) || (yval == 2.0))
00466          rval = 2.0;
00467       else 
00468          rval = xval*yval;                      // Note: handles cases where
00469                                                 //   either is Ind.
00470       }
00471    }
00472 }
00473 
00474 
00475 template <class Type>
00476 inline void Ereal<Type>::div(const Type xval, const bool xFinite, 
00477                 const Type yval, const bool yFinite, 
00478                 Type& rval, bool& rFinite)
00479 {
00480 if (xFinite) {
00481    if (yFinite) {
00482       if (yval == 0.0) {
00483          rFinite = false;
00484          if (xval > 0.0)
00485             rval = 1.0;
00486          else if (xval < 0.0)
00487             rval = -1.0;
00488          else 
00489             rval = 0.0;                    // Indeterminate: 0 / 0
00490          }
00491       else {
00492          rFinite = true;
00493          rval = xval / yval;
00494          check_if_infinite(rval,rFinite);
00495          }
00496       }
00497    else {
00498       rval = 0.0;
00499       rFinite = true;
00500       }
00501    }
00502 
00503 else {
00504    rFinite = false;
00505    if (yFinite) {
00506       if (yval < 0.0)
00507          rval = - xval;
00508       else if (yval == 0.0)
00509          rval = 0.0;                            // Indeterminate: infty / 0
00510       else
00511          rval = xval;
00512       }
00513    else
00514       rval = 0.0;                               // Indeterminate: 
00515                                                 //        +/- infty / +/- infty
00516    }
00517 }
00518 
00519 
00520 template <class Type> inline
00521 #if defined(NON_ANSI) || defined(COUGAR) || defined(SGI) || defined(OSF)
00522 ostream& Ereal<Type>::write(ostream& os) const
00523 #else
00524 std::ostream& Ereal<Type>::write(std::ostream& os) const
00525 #endif
00526 {
00527 if (Finite)
00528    os << val;
00529 else {
00530    if (val == -1.0)
00531       os << "-Infinity";
00532    else if (val == 1.0)
00533       os << "Infinity";
00534    else if (val == 2.0)
00535       os << "NaN";
00536    else if (val == 0.0)
00537       os << "Indeterminate";
00538    else
00539       os << "Ereal_Bad_Value=" << val;          // Generate error
00540    }
00541 return os;
00542 }
00543 
00544 
00545 template <class Type> inline
00546 #if defined(NON_ANSI) || defined(COUGAR) || defined(SGI) || defined(OSF)
00547 istream& Ereal<Type>::read(istream& is)
00548 #else
00549 std::istream& Ereal<Type>::read(std::istream& is)
00550 #endif
00551 {
00552 char c;
00553 is.get(c);
00554 
00555 bool neg_flag=false;
00556 if (c == '-') {
00557    neg_flag = true;
00558    is.get(c);
00559    }
00560 
00561 if (isdigit(c)) {
00562    is.putback(c);
00563    is >> val;
00564    if (neg_flag)
00565       val = -val;
00566    Finite = true;
00567    check_if_infinite(val,Finite);
00568    }
00569 else if (isalpha(c)) {
00570    is.get(c);
00571    if (c == 'I') {
00572       is.get(c);
00573       if (c != 'n') cout << "ERROR" << endl;
00574       is.get(c);
00575       if (c == 'd') {
00576          if (neg_flag) cout << "ERROR" << endl;
00577          // Read "Indeterminate" here...
00578          }
00579       else if (c == 'f') {
00580          // Read "Infinity" here...
00581          }
00582       else
00583          cout << "ERROR" << endl;
00584       }
00585    else if (c == 'N') {
00586       if (neg_flag) cout << "ERROR" << endl;
00587       // Read "NaN" here...
00588       }
00589    // else generate an exception
00590    }
00591 
00592 return is;
00593 }
00594 
00595 
00596 template <class Type> inline
00597 PackBuffer& Ereal<Type>::write(PackBuffer& os) const
00598 { os << Finite << val;  return os; }
00599 
00600 
00601 template <class Type> inline
00602 UnPackBuffer& Ereal<Type>::read(UnPackBuffer& is)
00603 { is >> Finite >> val; return is; }
00604 
00605 
00606 template <class Type> inline Ereal<Type>
00607 operator+ (const Ereal<Type>& x, const Ereal<Type>& y)
00608 {
00609 Type val;
00610 bool Finite;
00611 Ereal<Type>::plus(x.val, x.Finite, y.val, y.Finite, val, Finite);
00612 return Ereal<Type>(val,Finite);
00613 }
00614 
00615 
00616 template <class Type> inline Ereal<Type>
00617 operator+ (const Ereal<Type>& x, const Type y)
00618 {
00619 Type yval = y;
00620 bool yFinite = true;
00621 Ereal<Type>::check_if_infinite(yval,yFinite);
00622 
00623 Type val;
00624 bool Finite;
00625 Ereal<Type>::plus(x.val, x.Finite, yval, yFinite, val, Finite);
00626 return Ereal<Type>(val,Finite);
00627 }
00628 
00629 
00630 template <class Type> inline Ereal<Type>
00631 operator+ (const Type x, const Ereal<Type>& y)
00632 {
00633 Type xval = x;
00634 bool xFinite = true;
00635 Ereal<Type>::check_if_infinite(xval,xFinite);
00636 
00637 Type val;
00638 bool Finite;
00639 Ereal<Type>::plus(xval, xFinite, y.val, y.Finite, val, Finite);
00640 return Ereal<Type>(val,Finite);
00641 }
00642 
00643 
00644 template <class Type> inline Ereal<Type>
00645 operator- (const Ereal<Type>& x, const Ereal<Type>& y)
00646 {
00647 Type val;
00648 bool Finite;
00649 Ereal<Type>::minus(x.val, x.Finite, y.val, y.Finite, val, Finite);
00650 return Ereal<Type>(val,Finite);
00651 }
00652 
00653 
00654 template <class Type> inline Ereal<Type>
00655 operator- (const Ereal<Type>& x, const Type y)
00656 {
00657 Type yval = y;
00658 bool yFinite = true;
00659 Ereal<Type>::check_if_infinite(yval,yFinite);
00660 
00661 Type val;
00662 bool Finite;
00663 Ereal<Type>::minus(x.val, x.Finite, yval, yFinite, val, Finite);
00664 return Ereal<Type>(val,Finite);
00665 }
00666 
00667 
00668 template <class Type> inline Ereal<Type>
00669 operator- (const Type x, const Ereal<Type>& y)
00670 {
00671 Type xval = x;
00672 bool xFinite = true;
00673 Ereal<Type>::check_if_infinite(xval,xFinite);
00674 
00675 Type val;
00676 bool Finite;
00677 Ereal<Type>::minus(xval, xFinite, y.val, y.Finite, val, Finite);
00678 return Ereal<Type>(val,Finite);
00679 }
00680 
00681 
00682 template <class Type> inline Ereal<Type>
00683 operator* (const Ereal<Type>& x, const Ereal<Type>& y)
00684 {
00685 Type val;
00686 bool Finite;
00687 Ereal<Type>::mult(x.val, x.Finite, y.val, y.Finite, val, Finite);
00688 return Ereal<Type>(val,Finite);
00689 }
00690 
00691 
00692 template <class Type> inline Ereal<Type>
00693 operator* (const Ereal<Type>& x, const Type y)
00694 {
00695 Type yval = y;
00696 bool yFinite = true;
00697 Ereal<Type>::check_if_infinite(yval,yFinite);
00698 
00699 Type val;
00700 bool Finite;
00701 Ereal<Type>::mult(x.val, x.Finite, yval, yFinite, val, Finite);
00702 return Ereal<Type>(val,Finite);
00703 }
00704 
00705 
00706 template <class Type> inline Ereal<Type>
00707 operator* (const Type x, const Ereal<Type>& y)
00708 {
00709 Type xval = x;
00710 bool xFinite = true;
00711 Ereal<Type>::check_if_infinite(xval,xFinite);
00712 
00713 Type val;
00714 bool Finite;
00715 Ereal<Type>::mult(xval, xFinite, y.val, y.Finite, val, Finite);
00716 return Ereal<Type>(val,Finite);
00717 }
00718 
00719 
00720 template <class Type> Ereal<Type>
00721 operator/ (const Ereal<Type>& x, const Ereal<Type> y)
00722 {
00723 Type val;
00724 bool Finite;
00725 Ereal<Type>::div(x.val, x.Finite, y.val, y.Finite, val, Finite);
00726 return Ereal<Type>(val,Finite);
00727 }
00728 
00729 
00730 template <class Type> Ereal<Type>
00731 operator/ (const Ereal<Type>& x, const Type y)
00732 {
00733 Type yval = y;
00734 bool yFinite = true;
00735 Ereal<Type>::check_if_infinite(yval,yFinite);
00736 
00737 Type val;
00738 bool Finite;
00739 Ereal<Type>::div(x.val, x.Finite, yval, yFinite, val, Finite);
00740 return Ereal<Type>(val,Finite);
00741 }
00742 
00743 
00744 template <class Type> Ereal<Type>
00745 operator/ (const Type x, const Ereal<Type>& y)
00746 {
00747 Type xval = x;
00748 bool xFinite = true;
00749 Ereal<Type>::check_if_infinite(xval,xFinite);
00750 
00751 Type val;
00752 bool Finite;
00753 Ereal<Type>::div(xval, xFinite, y.val, y.Finite, val, Finite);
00754 return Ereal<Type>(val,Finite);
00755 }
00756 
00757 
00758 template <class Type> inline Ereal<Type>
00759 operator+ (const Ereal<Type>& x)
00760 { return x; }
00761 
00762 
00763 template <class Type> inline 
00764 Ereal<Type> operator- (const Ereal<Type>& num)
00765 {
00766 if (num.Finite)
00767    return Ereal<Type>(-num.val, num.Finite);
00768 else if (val == 1.0)
00769    return Ereal<Type>(-1.0, num.Finite);
00770 else if (val == -1.0)
00771    return Ereal<Type>(1.0, num.Finite);
00772 else 
00773    return num;
00774 }
00775 
00776 
00777 
00778 template <class Type> inline
00779 bool operator== (const Ereal<Type>& x, const Ereal<Type>& y)
00780 {
00781 if (x.Finite) {
00782    if (y.Finite)
00783       return (x.val == y.val);
00784    else
00785       return false; 
00786    }
00787 else {
00788    if (y.Finite)
00789       return false;
00790    else
00791       return (x.val == y.val);                  // Correct?
00792    }
00793 }
00794 
00795 
00796 template <class Type> inline
00797 bool operator== (const Ereal<Type>& x, const Type y)
00798 {
00799 if (x.Finite)
00800    return (x.val == y);
00801 return false;
00802 }
00803 
00804 
00805 template <class Type> inline
00806 bool operator== (const Type x, const Ereal<Type>& y)
00807 { return (y == x); }
00808 
00809 
00810 template <class Type> inline bool
00811 operator!= (const Ereal<Type>& x, const Ereal<Type>& y)
00812 { return (!(y == x)); }
00813 
00814 
00815 template <class Type> inline bool
00816 operator!= (const Ereal<Type>& x, const Type y)
00817 { return (!(y == x)); }
00818 
00819 
00820 template <class Type> inline bool
00821 operator!= (const Type x, const Ereal<Type>& y)
00822 { return (y != x); }
00823 
00824 
00825 template <class Type> inline
00826 bool operator> (const Ereal<Type>& x, const Ereal<Type>& y)
00827 { return (! (x <= y)); }
00828 
00829 
00830 template <class Type> inline
00831 bool operator> (const Ereal<Type>& x, const Type y)
00832 { return (! (x <= y)); }
00833 
00834 template <class Type> inline 
00835 bool operator> (const Type x, const Ereal<Type>& y)
00836 { return (!(x <= y)); }
00837 
00838 
00839 template <class Type> inline 
00840 bool operator>= (const Ereal<Type>& x, const Ereal<Type>& y)
00841 { return (!(x < y)); }
00842 
00843 
00844 template <class Type> inline 
00845 bool operator>= (const Type x, const Ereal<Type>& y)
00846 { return (!(x < y)); }
00847 
00848 
00849 template <class Type> inline 
00850 bool operator>= (const Ereal<Type>& x, const Type y)
00851 { return (!(x < y)); }
00852 
00853 
00854 template <class Type> inline
00855 bool operator< (const Ereal<Type>& x, const Ereal<Type>& y)
00856 {
00857 if (x.Finite) {
00858    if (y.Finite)
00859       return (x.val < y.val);
00860    else if (y.val == 1.0)
00861       return true;
00862    else if (y.val == -1.0)
00863       return false;                                     // TODO: errors
00864    return false;                                        // ERRORS!
00865    }
00866 
00867 else {
00868    if (y.Finite) {
00869       if (x.val == 1.0)
00870          return false;
00871       else if (x.val == -1.0)
00872          return true;
00873       return false;                                     // TODO: errors
00874       }
00875    else {
00876       if ((x.val == -1.0) && (y.val == 1.0))
00877          return true;
00878       return false;                                     // TODO: errors
00879       }
00880    }
00881 }
00882 
00883 
00884 template <class Type> inline
00885 bool operator< (const Ereal<Type>& x, const Type y)
00886 {
00887 if (x.Finite)
00888    return (x.val < y);
00889 
00890 else {
00891    if (x.val == 1.0)
00892       return false;
00893    else if (x.val == -1.0)
00894       return true;
00895    return false;                                        // TODO: errors
00896    }
00897 }
00898 
00899 
00900 template <class Type> inline bool
00901 operator< (const Type x, const Ereal<Type>& y)
00902 { return operator>=(y,x); }
00903 
00904 
00905 template <class Type> inline
00906 bool operator<= (const Ereal<Type>& x, const Ereal<Type>& y)
00907 {
00908 if (x.Finite) {
00909    if (y.Finite)
00910       return (x.val <= y.val);
00911    else if (y.val == 1.0)
00912       return true;
00913    else if (y.val == -1.0)
00914       return false;
00915    return false;                                        // TODO: errors
00916    }
00917 
00918 else {
00919    if (y.Finite) {
00920       if (x.val == 1.0)
00921          return false;
00922       else if (x.val == -1.0)
00923          return true; 
00924       return false;                                     // TODO: errors
00925       }
00926    else {
00927       if ((x.val == 1.0) && (y.val == -1.0))
00928          return false;
00929       return true;                                      // TODO: errors
00930       }
00931    }
00932 }
00933 
00934 
00935 template <class Type> inline
00936 bool operator<= (const Ereal<Type>& x, const Type y)
00937 {
00938 if (x.Finite)
00939    return (x.val <= y);
00940 
00941 else {
00942    if (x.val == 1.0)
00943       return false;
00944    else if (x.val == -1.0)
00945       return true;
00946    return false;                                        // TODO: errors
00947    }
00948 }
00949 
00950 
00951 template <class Type> inline bool
00952 operator<= (const Type x, const Ereal<Type>& y)
00953 { return operator>(y,x); }
00954 
00955 
00956 #if defined(NON_ANSI) || defined(COUGAR) || defined(SGI) || defined(OSF)
00957 template <class Type> inline
00958 istream& operator>> (istream& is, Ereal<Type>& num)
00959 { num.read(is); return is; }
00960 
00961 
00962 template <class Type> inline
00963 ostream& operator<< (ostream& os, const Ereal<Type>& num)
00964 { num.write(os); return os; }
00965 #else
00966 template <class Type> inline
00967 std::istream& operator>> (std::istream& is, Ereal<Type>& num)
00968 { num.read(is); return is; }
00969 
00970 
00971 template <class Type> inline
00972 std::ostream& operator<< (std::ostream& os, const Ereal<Type>& num)
00973 { num.write(os); return os; }
00974 #endif
00975 
00976 
00977 template <class Type> inline
00978 UnPackBuffer& operator>> (UnPackBuffer& is, Ereal<Type>& num)
00979 { return num.read(is); }
00980 
00981 
00982 template <class Type> inline
00983 PackBuffer& operator<< (PackBuffer& os, const Ereal<Type>& num)
00984 { return num.write(os); }
00985 
00986 
00987 template <class Type> inline
00988 bool isinf(const Ereal<Type>& num)
00989 { return (!num.Finite); }
00990 
00991 
00992 template <class Type> inline
00993 bool isnan(const Ereal<Type>& num)
00994 { return (!num.Finite && num.val == 2.0); }
00995 
00996 
00997 template <class Type> inline
00998 bool isind(const Ereal<Type>& num)
00999 { return (!num.Finite && num.val == 0.0); }
01000 
01001 
01002 template <class Type> inline
01003 bool finite(const Ereal<Type>& num)
01004 { return (num.Finite); }
01005 
01006 
01007 template<class Type>
01008 Type Ereal<Type>::positive_infinity_val = (Type) 1e16;
01009 
01010 
01011 template<class Type>
01012 Type Ereal<Type>::negative_infinity_val = (Type) -1e16;
01013 
01014 
01015 #ifdef COUGAR
01016 //
01017 // WEH - I think that these really _do_ belong in a source file, but
01018 // the Janus compilers don't seem to agree.
01019 //
01020 template<>
01021 double Ereal<double>::positive_infinity_val = MAXDOUBLE;
01022 
01023 
01024 template<>
01025 double Ereal<double>::negative_infinity_val = -MAXDOUBLE;
01026 
01027 
01028 template<>
01029 float Ereal<float>::positive_infinity_val = MAXFLOAT;
01030 
01031 
01032 template<>
01033 float Ereal<float>::negative_infinity_val = -MAXFLOAT;
01034 #endif
01035 
01036 #endif