home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / progjour / 1991 / 03 / except.cpp < prev    next >
C/C++ Source or Header  |  1991-04-17  |  6KB  |  265 lines

  1. #ifdef __ZTC__
  2. #include <stream.hpp>
  3. #endif
  4. #ifdef __TURBOC__
  5. #include <iostream.h>
  6. #endif
  7. #include <stdio.h>
  8. #include <string.h>
  9. #include <stdlib.h>    // for exit() prototype
  10.  
  11. /* define only on of these to 1 */
  12. /* #define BIT32 */
  13. #define BIT16    1            /* we have a 16-bit compiler */
  14.  
  15. #ifdef BIT32
  16. #define INT    int
  17. #else
  18. #define INT long            /* for 16-bit C++ compilers */
  19. #endif
  20.  
  21. const unsigned INT QNAN =   0x7FFFFFFF;
  22. const unsigned INT SNAN =   0x7FC00000;
  23. const unsigned INT INF  =   0x7F800000;
  24. const unsigned INT ZERO =   0x00000000;
  25. const unsigned INT DENORM = 0x00000001;
  26. const unsigned INT NORM =   0x00800000;
  27.  
  28. //
  29. //  This is a class definition for single precision IEEE-854-Std arithmetic.
  30. //  class real is by no means complete - it is the basic outline for
  31. //  implementing a portable numerics system.
  32. //
  33.  
  34. class real {
  35.    private:
  36.       union {
  37.      float f;
  38.      unsigned INT i;
  39.      };
  40.    public:
  41.  
  42.       // constructors
  43.  
  44.       real();         
  45.       real(char *);   
  46.       real(float f);
  47.       real(double d);
  48.       real(char c);
  49.       real(short s);
  50.       real(INT i);
  51.  
  52.       // No destructors really necessary
  53.  
  54.       // some basic primitives
  55.  
  56.       inline friend int isqnan(real &r);
  57.       inline friend int issnan(real &r);
  58.       inline friend int iszero(real &r);
  59.       inline friend int isinf(real &r);
  60.       inline friend int isdenorm(real &r);
  61.       inline friend int isnorm(real &r);
  62.  
  63.       // overloaded operators
  64.        
  65.       friend real operator+( real &, real & );
  66.       friend real operator-( real &, real & );
  67.       friend real operator*( real &, real & );
  68.       friend real &operator/( real &, real & );
  69.  
  70.       friend int operator==( real &, real & );
  71.       friend int operator!=( real &, real & );
  72.       friend int operator> ( real &, real & );
  73.       friend int operator>=( real &, real & );
  74.       friend int operator<=( real &, real & );
  75.       friend int operator< ( real &, real & );
  76.  
  77.       inline void print(void) { cout << f; }
  78.  
  79.       }; // end of class real
  80.  
  81. // I/O related overloads
  82.  
  83. ostream &operator << (ostream &out, real &r) {
  84. /*   r.print();        this was an error in magazine listing */
  85.    if (isqnan(r)) cout << " QNAN ";
  86.    else if (issnan(r)) cout << " SNAN ";
  87.    else if (isinf(r)) cout << " INF ";
  88.    else if (isdenorm(r)) cout << " DENORM ";
  89.    else r.print();
  90.  
  91.    return out;
  92.    }
  93.  
  94. istream &operator >> (istream &in, real &r) {
  95.  
  96.    return in;
  97.    }
  98.  
  99. real::real() {}  // allow uninitialized variables
  100.  
  101. real::real(char *str){
  102.    if (strcmp(str,"INF") == 0)
  103.       i = INF;
  104.    else if (strcmp(str,"QNAN") == 0)
  105.       i = QNAN;
  106.    else if (strcmp(str,"SNAN") == 0)
  107.       i = SNAN;
  108.    else if (strcmp(str,"ZERO") == 0)
  109.       i = ZERO;
  110.    else if (strcmp(str,"DENORM") == 0)
  111.       i = DENORM;
  112.    else if (strcmp(str,"NORM") == 0)
  113.       i = NORM;
  114.    else {
  115.       cout << "Unrecognized string format :" << str << ":\n";
  116.       exit(1);
  117.       }
  118.    }
  119.  
  120. real::real(float fl){ f = fl; }
  121.  
  122. real::real(double d){ f = float(d); }
  123.  
  124. real::real(char c){ f = float(c); }
  125.  
  126. real::real(short s){ f = float(s); }
  127.  
  128. real::real(INT I){ f = float(I); }
  129.  
  130. int isqnan( real &r ){
  131.    unsigned INT i = r.i;
  132.    if ((i >= 0x7FC00000) && (i <= 0x7FFFFFFF))
  133.       return 1;
  134.    return 0;
  135.    }
  136.  
  137. int issnan( real &r ){
  138.    unsigned INT i = r.i;
  139.    if ((i >= 0x7F800001) && (i <= 0x7FBFFFFF))
  140.       return 1;
  141.    return 0;
  142.    }
  143.  
  144. int iszero( real &r ){
  145.    unsigned INT i = r.i;
  146.    if (i == 0)
  147.       return 1;
  148.    return 0;
  149.    }
  150.  
  151. int isinf( real &r ){
  152.    unsigned INT i = r.i;
  153.    if (i == 0x7F800000)
  154.       return 1;
  155.    return 0;
  156.    }
  157.  
  158. int isdenorm( real &r ){
  159.    unsigned INT i = r.i;
  160.    if ((i >= 0x00000001) && (i <= 0x007FFFFF))
  161.       return 1;
  162.    return 0;
  163.    }
  164.  
  165. int isnorm( real &r ){
  166.    unsigned INT i = r.i;
  167.    if ((i >= 0x00800000) && (i <= 0x7F7FFFFF))
  168.       return 1;
  169.    return 0; 
  170.    }
  171.  
  172. int operator==( real &num, real &dem ){
  173.    // this is a skeleton == operator for reals
  174.    if (isnorm(num) && isnorm(num)) return (num.i == dem.i);
  175.    else if (isqnan(num) && isqnan(dem)) return 1;
  176.    else if (issnan(num) && issnan(dem)) return 1;
  177.    else if (isinf(num) && isinf(dem)) return 1;
  178.    else if (isdenorm(num) && isdenorm(dem)) return 1;
  179.    return 0; 
  180.    }
  181.  
  182. const char DIV_BY_NAN = 0;
  183. const char DIV_BY_QNAN = 1;
  184. const char DIV_BY_ZERO = 2;
  185. const char INVALID_OP = 3;
  186. const char DIV_BY_INF = 4;
  187.  
  188. void set_psr(char c){
  189.    // a stub for setting a user controlled processor control word
  190.    }
  191.  
  192. real result;
  193.  
  194. real& operator/(real &nom, real &dem) {
  195.    if (isqnan(nom) || isqnan(dem) || issnan(nom) || issnan(dem)){
  196.       set_psr(DIV_BY_NAN);
  197.       result.i = QNAN;
  198.       return result;
  199.       }
  200.    else if (iszero(nom) && iszero(dem)){
  201.       set_psr( DIV_BY_QNAN );
  202.       result.i = QNAN;
  203.       return result;
  204.       }
  205.    else if (iszero(dem)) {
  206.       set_psr( DIV_BY_ZERO );
  207.       result.i = INF;
  208.       return result;
  209.       }
  210.    else if (isinf(nom) && isinf(dem)) {
  211.       set_psr( INVALID_OP );
  212.       result.i = QNAN;
  213.       return result;
  214.       }
  215.    else if (isinf(nom) && isnorm(dem)) {
  216.       set_psr( DIV_BY_INF );
  217.       result.i = INF;
  218.       return result;
  219.       }
  220.    else if ((isnorm(nom) || iszero(nom)) && isinf(dem)) {
  221.       result.i = ZERO;
  222.       return result;
  223.       }
  224.    result.f = float(nom.f) / float(dem.f);
  225.    return result;
  226.    }  // end of real::operator/
  227.  
  228. /*
  229. **  A very simple program showing real assignments, divide operations,
  230. **  output routines, and comparisons.
  231. */
  232.  
  233. int main(void) {
  234.  
  235.    real r1;
  236.    real r2 = 0.0;
  237.    real r3 = 1.0;
  238.    real rinf = "INF";
  239.    real rqnan = "QNAN";
  240.    real rsnan = "SNAN";
  241.    real rzero = "ZERO";
  242.    real rdenorm = "DENORM";
  243.  
  244.    cout << "r1 = " << r1 << "\n";
  245.    cout << "r2 = " << r2 << "\n";
  246.    cout << "r3 = " << r3 << "\n";
  247.    cout << "rinf = " << rinf << "\n";
  248.    cout << "rqnan = " << rqnan << "\n";
  249.    cout << "rsnan = " << rsnan << "\n";
  250.    cout << "rzero = " << rzero << "\n";
  251.    cout << "rdenorm = " << rdenorm << "\n";
  252.  
  253.    r1 = r3 / r2;   // this should generate an INF
  254.    cout << "r1 = INF ?? " << r1 << "\n";
  255.  
  256.    r1 = rqnan / rqnan;  // this should generate a QNAN
  257.    cout << "rqnan = QNAN ?? " << rqnan << "\n";
  258.  
  259.    if (r1 == rsnan)
  260.       cout << "WRONG!!! QNAN == SNAN\n";
  261.    else
  262.       cout << "RIGHT!!! QNAN != SNAN\n";
  263.  
  264.    } // end of main
  265.