Reputation: 7809
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?
Upvotes: 3
Views: 504
Reputation: 41331
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.
Upvotes: 1
Reputation: 95499
So, firstly, you probably want to pass around const Polynomial&
instead of Polynomial
to your functions, since the latter creates a copy, while the former passes by constant reference.
Secondly, I find it very strange that you are writing:
Polynomial b = *this;
Instead of writing b.coeff[i]
, you can simply write coef[i]
, since it resolves to this->coef[i]
. If you absolutely must use some other variable b
, though, then I suggest you use the following when reading:
const Polynomial& b = *this;
And use the following when writing:
Polynomial& b = *this;
Note that if you use Polynomial
instead of Polynomial&
, then your b variable is a copy and is not identical to *this
; consequently, changes you make will not affect *this
as intended.
That said, writing deg = //...
is clearer than a.deg = //...
, where a
represents *this
. I strongly suggest you get out of the habit of creating variables that (attempt to) reference *this
.
One last note, as has been stated in a comment, assignment operators should return a reference to the type. So, your operator=
, operator+=
, operator-=
, etc. should return Polynomial&
. The reason for this is to allow efficient chaining in an assignment statement. For example: a = b = c
. If you were to return void
, then this wouldn't work at all. With returning a copy of a Polynomial
, it will work, but it will neeedlessly construct copies. Using a reference in this case (i.e. Polynomial&
) prevents the copying.
Upvotes: 1
Reputation: 54604
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.
Upvotes: 8