home *** CD-ROM | disk | FTP | other *** search
/ DP Tool Club 24 / CD_ASCQ_24_0995.iso / vrac / fracti10.zip / FRACTION.CPP < prev    next >
C/C++ Source or Header  |  1994-11-06  |  6KB  |  295 lines

  1. // General Fraction class - also handles Mixed Numbers & Decimals
  2.  
  3.  
  4. // M\Cooper
  5. // 3425 Chestnut Ridge Rd.
  6. // Grantsville, MD 21536-9801
  7. // --------------------------
  8. // Email:  thegrendel@aol.com
  9.  
  10.  
  11. #include <iostream.h>
  12. #include <stdlib.h>
  13. #include <string.h>
  14.  
  15. #define MAXLEN 30
  16. #define ARGCOUNT 4
  17. #define OPERATOR_ERROR 5
  18. #define WRONG_NO_OF_ARGS 2
  19. #define MAXIMUM(x,y) (x>=y) ? x:y
  20. #define SLASH '/'
  21. #define DASH '-'
  22. #define TERM1 argv[1]
  23. #define OP   *argv[2]
  24. #define TERM2 argv[3]
  25. #define POSITIVE 0
  26. #define NEGATIVE 1
  27.  
  28. const long SCALING_FACTOR = 1000;
  29.  
  30. enum boolean {FALSE, TRUE};
  31.  
  32. void input_error();
  33.  
  34. class Fraction
  35.     {
  36.     protected:
  37.         long numerator;
  38.         long denominator;
  39.         double decimal_equivalent;
  40.  
  41.         long integer_part;
  42.         long part_numerator;
  43.         long part_denominator;
  44.  
  45.     public:
  46.         Fraction()
  47.             { numerator = 0; denominator = 1;
  48.               part_numerator = 0; part_denominator = 1;
  49.               decimal_equivalent = 0.; integer_part = 0;} 
  50.  
  51.         Fraction( long num, long denom )
  52.             {
  53.               numerator =   num;
  54.               denominator = denom;
  55.               decimal_equivalent = (double)numerator/(double)denominator;
  56.               part_numerator = 0; part_denominator = 1;
  57.               integer_part = 0;
  58.             }
  59.         Fraction( double decimal )
  60.             {
  61.              numerator =   (long) (SCALING_FACTOR * decimal);
  62.              denominator = SCALING_FACTOR;
  63.              decimal_equivalent = decimal;
  64.              part_numerator = 0; part_denominator = 1;
  65.              integer_part = 0;
  66.              }
  67.  
  68.       
  69.         void show()
  70.             {
  71.             cout << "The result: " 
  72.                   << numerator << SLASH << denominator << endl;
  73.  
  74.             if( integer_part )
  75.                 {
  76.                 cout << "Converted to a mixed number: " << integer_part;
  77.                     if( part_numerator )
  78.                         cout << "-" << part_numerator << SLASH << part_denominator
  79.                               << endl;
  80.                 }
  81.             cout << "Decimal equivalent = " << decimal_equivalent << endl;
  82.             }
  83.  
  84.         Fraction operator + (Fraction fr)  // addition
  85.         {
  86.         long num, denom;
  87.  
  88.              if( denominator == fr.denominator )
  89.                  { 
  90.                  num =   numerator + fr.numerator;
  91.                  denom = denominator;
  92.                  }
  93.              else
  94.                  {
  95.                  num   = numerator * fr.denominator
  96.                          + fr.numerator * denominator;
  97.                  denom = denominator * fr.denominator;
  98.                  }
  99.  
  100.              return ( Fraction(num,denom) );
  101.         }
  102.  
  103.         Fraction operator - (Fraction fr)    // subtraction
  104.         {
  105.         long num, denom;
  106.  
  107.             if( denominator == fr.denominator )
  108.                 {
  109.                 num =   numerator - fr.numerator;
  110.                 denom = denominator;
  111.                 }
  112.             else
  113.                 {
  114.                 num   = numerator * fr.denominator
  115.                         - fr.numerator * denominator;
  116.                 denom = denominator * fr.denominator;
  117.                 }
  118.  
  119.             return  ( Fraction(num,denom) );
  120.         }     
  121.  
  122.         Fraction operator * (Fraction fr)     // multiplication
  123.         {
  124.             long num =   numerator * fr.numerator;
  125.             long denom = denominator * fr.denominator;
  126.  
  127.             return ( Fraction(num,denom) );
  128.          }
  129.  
  130.          Fraction operator / (Fraction fr)   // division
  131.          {
  132.              long num =   numerator * fr.denominator;
  133.              long denom = denominator * fr.numerator;
  134.  
  135.              return ( Fraction(num,denom) );
  136.          }
  137.  
  138.         Fraction parse( char * );
  139.         boolean isfactor( long, long );
  140.         long gcf( long, long );
  141.         void reduce();
  142.         void improper_to_proper();
  143.         void proper_to_improper();
  144.  
  145.      };
  146.  
  147. boolean Fraction::isfactor( long number, long factor )
  148.     {
  149.     if( !(number % factor) )
  150.         return (TRUE);
  151.     else
  152.         return (FALSE);
  153.     }
  154.  
  155. long Fraction::gcf( long num, long denom )
  156.     {
  157.         long smaller,
  158.               larger,
  159.               temp;
  160.  
  161.             larger = MAXIMUM(num,denom);
  162.             smaller = temp = (num==larger) ? denom : num;
  163.  
  164.             while( temp )
  165.                 if( isfactor( smaller, temp ) && isfactor( larger, temp ) )
  166.                     break;
  167.                 else
  168.                     temp--;
  169.  
  170.             return (temp);
  171.     }
  172.  
  173. void Fraction::reduce()
  174.     {
  175.     long temp;
  176.     int sign = POSITIVE;
  177.  
  178.         if( numerator < 0)    //negative fraction
  179.             { sign = NEGATIVE; numerator *= -1; }
  180.  
  181.         while( (temp = gcf( numerator, denominator ) ) >1 )
  182.             { numerator /= temp; denominator /= temp; }
  183.  
  184.         if( sign )
  185.             numerator *= -1;   //change back to negative
  186.  
  187.         return;
  188.         }
  189.  
  190.  
  191. void Fraction::improper_to_proper()
  192.     {
  193.     if( labs(numerator) >= denominator )
  194.         {
  195.         integer_part = numerator / denominator;
  196.         part_numerator = labs( numerator - denominator * integer_part) ;
  197.         part_denominator = denominator;
  198.         }
  199.     else
  200.         {
  201.         integer_part = 0;
  202.         part_numerator = numerator;
  203.         part_denominator = denominator;
  204.         }
  205.     }
  206.  
  207. void Fraction::proper_to_improper()
  208.     { numerator = numerator + integer_part*denominator; }
  209.  
  210. Fraction Fraction::parse( char *token )
  211. {
  212.     char *denom_ptr,
  213.           *dash_ptr;
  214.     Fraction temp;
  215.  
  216.     if ( (dash_ptr = strchr( ++token, DASH )) != NULL )
  217.             // skip 1st char., in case minus sign...
  218.             {
  219.             temp.integer_part = atol( --token );  // renormalize
  220.             token = ++dash_ptr;
  221.             }
  222.      else --token;   // renormalize
  223.     
  224.      if( (denom_ptr = strchr( token, SLASH )) != NULL )
  225.          {
  226.          temp.numerator = atol( token );
  227.          temp.denominator = atol( ++denom_ptr );
  228.          temp.proper_to_improper();
  229.          temp.decimal_equivalent =
  230.          (double)temp.numerator/(double)temp.denominator;   
  231.          }
  232.      else
  233.          temp = atof( token );
  234.  
  235.      return (temp);
  236. }         
  237.  
  238. Fraction operation_on( Fraction& t1, Fraction& t2, char oper )
  239. {
  240.    Fraction temp;
  241.  
  242.      switch (oper)
  243.      {
  244.          case '+':   
  245.              temp = t1 + t2;
  246.              break;
  247.          case '-':
  248.              temp = t1 - t2;
  249.              break;
  250.          case '*':
  251.              temp = t1 * t2;
  252.              break;
  253.          case '/':
  254.              temp = t1 / t2;
  255.              break;
  256.          default:
  257.              input_error();
  258.              exit( OPERATOR_ERROR );
  259.      }
  260.  
  261.       return (temp) ;
  262. }
  263.  
  264.  
  265.  
  266. void main( int argc, char* argv[] )
  267.      {
  268.  
  269.      Fraction term1,
  270.                  term2, 
  271.                  result;
  272.  
  273.      if( argc != ARGCOUNT )
  274.          input_error();
  275.  
  276.         term1 = term1.parse( TERM1 );
  277.         term2 = term2.parse( TERM2 );
  278.         result = operation_on( term1, term2, OP );
  279.  
  280.      result.reduce();
  281.      result.improper_to_proper();
  282.      result.show();
  283.  
  284.      }
  285.  
  286.      void input_error()
  287.      {
  288.          cout << endl
  289.                 << "Format: fraction aaa/bbb <operator> ccc/ddd" << endl
  290.                 << "                             or" << endl
  291.                 << "             AAA-aaa/bbb <operator> CCC-ccc/ddd" << endl;
  292.  
  293.           exit( WRONG_NO_OF_ARGS );
  294.      }
  295.