tags:

views:

120

answers:

3

I have the following Polynomial class I'm working on:

#include <iostream>

using namespace std;

class Polynomial
{
//define private member functions
private:
   int coef[100];  // array of coefficients
   // coef[0] would hold all coefficients of x^0
   // coef[1] would hold all x^1
   // coef[n] = x^n ...

   int deg;        // degree of polynomial (0 for the zero polynomial)

//define public member functions
public:
   Polynomial::Polynomial() //default constructor
   {
      for ( int i = 0; i < 100; i++ )
      {
         coef[i] = 0;
      }
   }
   void set ( int a , int b ) //setter function
   {
      //coef = new Polynomial[b+1];
      coef[b] = a;
      deg = degree();
   }

   int degree()
   {
      int d = 0;
      for ( int i = 0; i < 100; i++ )
         if ( coef[i] != 0 ) d = i;
      return d;
   }

   void print()
   {
      for ( int i = 99; i >= 0; i-- ) {
         if ( coef[i] != 0 ) {
            cout << coef[i] << "x^" << i << " ";
         }
      }
   }

   // use Horner's method to compute and return the polynomial evaluated at x
   int evaluate ( int x )
   {
      int p = 0;
      for ( int i = deg; i >= 0; i-- )
         p = coef[i] + ( x * p );
      return p;
   }

   // differentiate this polynomial and return it
   Polynomial differentiate()
   {
      if ( deg == 0 )  {
         Polynomial t;
         t.set ( 0, 0 );
         return t;
      }
      Polynomial deriv;// = new Polynomial ( 0, deg - 1 );
      deriv.deg = deg - 1;
      for ( int i = 0; i < deg; i++ )
         deriv.coef[i] = ( i + 1 ) * coef[i + 1];
      return deriv;
   }

   Polynomial Polynomial::operator + ( Polynomial b )
   {
      Polynomial a = *this; //a is the poly on the L.H.S
      Polynomial c;

      for ( int i = 0; i <= a.deg; i++ ) c.coef[i] += a.coef[i];
      for ( int i = 0; i <= b.deg; i++ ) c.coef[i] += b.coef[i];
      c.deg = c.degree();

      return c;
   }

   Polynomial Polynomial::operator += ( Polynomial b )
   {
      Polynomial a = *this; //a is the poly on the L.H.S
      Polynomial c;

      for ( int i = 0; i <= a.deg; i++ ) c.coef[i] += a.coef[i];
      for ( int i = 0; i <= b.deg; i++ ) c.coef[i] += b.coef[i];
      c.deg = c.degree();

      for ( int i = 0; i < 100; i++) a.coef[i] = c.coef[i];
      a.deg = a.degree();

      return a;
   }

   Polynomial Polynomial::operator -= ( Polynomial b )
   {
      Polynomial a = *this; //a is the poly on the L.H.S

      Polynomial c;

      for ( int i = 0; i <= a.deg; i++ ) c.coef[i] += a.coef[i];
      for ( int i = 0; i <= b.deg; i++ ) c.coef[i] -= b.coef[i];
      c.deg = c.degree();


      for ( int i = 0; i < 100; i++) a.coef[i] = c.coef[i];
      a.deg = a.degree();

      return a;
   }

   Polynomial Polynomial::operator *= ( Polynomial b )
   {
      Polynomial a = *this; //a is the poly on the L.H.S
      Polynomial c;

      for ( int i = 0; i <= a.deg; i++ )
         for ( int j = 0; j <= b.deg; j++ )
            c.coef[i+j] += ( a.coef[i] * b.coef[j] );
      c.deg = c.degree();

      for ( int i = 0; i < 100; i++) a.coef[i] = c.coef[i];
      a.deg = a.degree();

      return a;
   }

   Polynomial Polynomial::operator - ( Polynomial b )
   {
      Polynomial a = *this; //a is the poly on the L.H.S
      Polynomial c;

      for ( int i = 0; i <= a.deg; i++ ) c.coef[i] += a.coef[i];
      for ( int i = 0; i <= b.deg; i++ ) c.coef[i] -= b.coef[i];
      c.deg = c.degree();


      return c;
   }

   Polynomial Polynomial::operator * ( Polynomial b )
   {
      Polynomial a = *this; //a is the poly on the L.H.S
      Polynomial c;

      for ( int i = 0; i <= a.deg; i++ )
         for ( int j = 0; j <= b.deg; j++ )
            c.coef[i+j] += ( a.coef[i] * b.coef[j] );
      c.deg = c.degree();
      return c;
   }
};

int main()
{
   Polynomial a, b, c, d;
   a.set ( 7, 4 ); //7x^4
   a.set ( 1, 2 ); //x^2

   b.set ( 6, 3 ); //6x^3
   b.set ( -3, 2 ); //-3x^2

   c = a - b; // (7x^4 + x^2) - (6x^3 - 3x^2)
   a -= b;

   c.print();
   cout << "\n";


   a.print();
   cout << "\n";


   c = a * b; // (7x^4 + x^2) * (6x^3 - 3x^2)
   c.print();

   cout << "\n";

   d = c.differentiate().differentiate();
   d.print();

   cout << "\n";

   cout << c.evaluate ( 2 ); //substitue x with 2

   cin.get();
}

Now, I have the "-" operator overloaded and it works fine:

Polynomial Polynomial::operator - ( Polynomial b )
   {
      Polynomial a = *this; //a is the poly on the L.H.S
      Polynomial c;

      for ( int i = 0; i <= a.deg; i++ ) c.coef[i] += a.coef[i];
      for ( int i = 0; i <= b.deg; i++ ) c.coef[i] -= b.coef[i];
      c.deg = c.degree();

      return c;
   }

However, I'm having difficulty with my "-=" operator:

Polynomial Polynomial::operator -= ( Polynomial b )
   {
      Polynomial a = *this; //a is the poly on the L.H.S

      Polynomial c;

      for ( int i = 0; i <= a.deg; i++ ) c.coef[i] += a.coef[i];
      for ( int i = 0; i <= b.deg; i++ ) c.coef[i] -= b.coef[i];
      c.deg = c.degree();

      // overwrite value of 'a' with the newly computed 'c' before returning 'a'
      for ( int i = 0; i < 100; i++) a.coef[i] = c.coef[i];
      a.deg = a.degree();

      return a;
   }

I just slightly modified my "-" operator method to overwrite the value in 'a' and return 'a', and just use the 'c' polynomial as a temp.

I've put in some debug print statement and I confirm that at the time of computation, both:

c = a - b;

and

a -= b;

are computed to the same value.

However, when I go to print them, their results are different:

Polynomial a, b; a.set ( 7, 4 ); //7x^4 a.set ( 1, 2 ); //x^2

b.set ( 6, 3 ); //6x^3 b.set ( -3, 2 ); //-3x^2

c = a - b; // (7x^4 + x^2) - (6x^3 - 3x^2) a -= b;

c.print(); cout << "\n";

a.print(); cout << "\n";

Result:

7x^4 -6x^3 4x^2

7x^4 1x^2

Why is my c = a - b and a -= b giving me different results when I go to print them?

+8  A: 

Polynomial::operator -= isn't modifying this, it's modifying a copy of this. If you change Polynomial a= *this to Polynomial &a= *this, i.e., make a reference instead of a copy, it will work as you are now modifying *this through a. Also, the return value of operator <op>= is usually a reference, not a value.

MSN
Potatoswatter
+1  A: 
Michael Aaron Safyan
+1  A: 

Operator -= should be modifying the left-hand value (and return a reference to *this to allow chaining).

It is also common to implement these functions in terms of the other:

//random example
X& operator+= (const X& other) 
{ 
    this->sth += other.sth; 
    return *this; 
}

//free function in terms of the previous
//more verbose than needed for exposition
X operator+ (const X& lhv, const X& rhv)
{
    X result(lhv);
    result += rhv;
    return result;
}

In fact most operators can (and should) be implemented in terms of others, and there's even Boost.Operators to synthesize related operators from existing ones.

UncleBens
And of course subtraction, is just addition of the negative of the second operand.
JohnMcG
If your prof lets you use Boost... ^_-
Mike DeSimone