Physics 5  Scientific Computing                             

Class Notes from 3/31/2011

 

During lecture we developed the Rational class for working with rational numbers.  Here’s some code related to what we did.  That Rational class has two private data member of type int and a number of member functions for dealing with this.  Generally, when developing a project involving a class like this, three files are included: the header file Rational.h, which includes the Class definition and prototypes:

// Rational.h

 

class Rational

{   public:

      Rational(int, int);  // Constructor

      void print(int); 

      Rational operator+( Rational &rhp ); //&rhp is the right hand part

      Rational operator-( Rational &rhp );

      Rational reduce();

      void showDecimal(int, int);

      // add additional method prototypes like reciprocal() or continued()

    private:

      int _num;              // numerator

      int _den;              // denominator

};

 

A second file that extends the class definition by defining these functions.  Notice the inclusion of Rational.h here:

// rationalFtns.cpp

#include "DarkGDK.h"

#include "Rational.h"

 

// Constructor has not return type. 

// All class definitions require scope resolution operator (::)

Rational::Rational(int num, int den) { _num = num; _den = den; }

 

//  There is a logic bug in print()...

//  sometimes an extra space is allocated

//  to the denominator.  Can you fix it?

//  The units are in pixels - a character requires at least 8 x 8 pixels

//  Where is dbStr() documented?  Anybody?

 

//  Use 1 + log to base ten of number for its base 10 digits.

void Rational::print(int line) {

    dbText(10,line,dbStr(_num));  // Here 10 is the starting  
                                 // indentation...parameterize?

    dbText(19+8*(int)(log((float)_num)/log(10.)),line,"/"); 

    // counting in pixels here

    dbText(27+8*(int)(1+log((float)_den)/log(10.)),line,dbStr(_den));    
    //running sum is oft off

// end print

 

//  Overloading the binary operators follows the template

Rational Rational::operator+(Rational &rhp) {

      int num = rhp._num*_den + rhp._den*_num;

      int den = rhp._den*_den;

      Rational temp(num, den);

      return temp;

}

 

Rational Rational::operator-(Rational &rhp) { 

      int num = rhp._num*_den - rhp._den*_num;

      int den = rhp._den*_den;

      Rational temp(num, den);

      return temp;

}

 

Rational Rational::reduce() {

      // Euclidean algorithm here

      int a = _num, b = _den, temp;

      if(a < b) {

            temp = a;

            a = b;

            b = temp;

      }

      while(a%b != 0) {

            temp = a%b;

            a = b;

            b = temp;

      }

      return Rational(_num/b,_den/b);

}

 

void Rational::showDecimal(int hor, int ver) {

      dbText(hor,ver,dbStr((float)_num/(float)_den));

}


Finally, a third file containing the
main() function, or the DarkGDK() function, which serves the purpose of main() in the Dark GDK environment.  This main function serves to check how the various methods in the Rational class work:

//  DarkGDKtest.cpp for testing Rational class methods

 

#include "DarkGDK.h"

#include "Rational.h"

 

void DarkGDK()

{   Rational t(0,1);

    for(int i = 1; i < 20; i++) {

        Rational r(i,i+1), s(i+2,i+3);  // constructs objects r, and s

        t = r + s; //compute the sum of r and s using overloaded operator+

        t.reduce().print(i*12);// calls the print() function                      
                              // for the object t with multiples of 12 pixels

        t.showDecimal(120,i*12); // compute decimal

    } // end for

    dbWaitKey();

}

 

Here is the output of this program:

RationalsOutput.jpg

 

Note that there is an awkward space that sometimes appears in the denominator and sometimes doesn’t.  That would be something to fix…

Also note that the decimal() function requires a bunch of awkward casts put together in a kluge that produces results.  The decimals are float types, so the accuracy fails after 8 significant digits or so, but that dbStr() will not take a double…weird, huh?  Try googling “dbStr float” and this web site is the third hit from the top.  We’re famous!

An interesting exercise is to write a function that will take a fraction, say, m/n and produce the continued fraction up to, say, 8 levels: