Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
Solved

Need help with Polynomial class

Posted on 2003-03-04
Medium Priority
1,144 Views
I am having problems with my implimenation file. The functions reserve, eval and addition keep are where the bulk of my errors coming up. I can't understand why because i have seen it written the same way by other and they had no problems.

// Driver program for the polynomial class

#include <iostream>
#include "poly.h"

using namespace std;

void cctest(polynomial);

int main()
{
polynomial P1, P2, P3;
int howmany;
double c, x, result;
unsigned int e;

cout << "Enter how many coeffiecients the polynomial : ";
cin >> howmany;
while (howmany > 0)
{
cout << "Enter coefficient : ";
cin >> c;
cout << "Enter exponent : ";
cin >> e;
P1.assign_coef(c,e);
howmany--;
}

cout << "Enter how many coeffiecients the polynomial : ";
cin >> howmany;
while (howmany > 0)
{
cout << "Enter coefficient : ";
cin >> c;
cout << "Enter exponent : ";
cin >> e;
P2.assign_coef(c,e);
howmany--;
}

cout << "The first polynomial is " << P1 << endl
<< "The second polynomial is " << P2 << endl << endl;

P3 = P2;
cout << "Testing = operator ... " << endl
<< "The second polynomial is " << P3 << endl << endl;

cout << "Results of Addition : " << P1 + P2 << endl;
cout << "Results of Subtraction : " << P1 - P2 << endl << endl;

cout << "Testing Evaluate ..." << endl;
cout << "  Enter value of x : ";
cin >> x;
result = P1.eval(x);
cout << "  The result of P1 when x is " << x << " is " << result << endl << endl;

cout << "Testing copy constructor..." << endl;
cctest(P1);

return 0;
}

void cctest(polynomial P)
{
cout << "  The first polynomial is " << P << endl << endl;
}

// CLASS IMPLEMENTED: polynomial (see poly1.h for documentation)
// INVARIANT for the polynomial class:
//   1. coef points to a dynamic array with size elements.
//   2. For each k < size, the coefficient of the x^k term is
//      stored in coef[k].
//   3. The degree of the polynomial is stored in current_degree
//      (using zero for the case of all zero coefficients).

#include <cassert>   // Provides assert
#include <cmath>     // Provides pow
#include <iostream>  // Provides ostream
#include "poly.h"

using namespace std;

polynomial::polynomial(const polynomial& source)
{
coef = new double[source.size];
size = source.size;
current_degree = source.current_degree;
for (int i = 0; i < size; i++)
coef[i] = source.coef[i];
}

void polynomial::operator=(const polynomial& source)
{
double *new_coef;

if (this == &source)
return;
if (size != source.size)
{
new_coef = new double[source.size];
delete [ ] coef;
coef = new_coef;
size = source.size;
}

current_degree = source.current_degree;
for(size_t i = 0; i < size; i++)
coef[i] = source.coef[i];
}

void polynomial::assign_coef(double coefficient, unsigned int exponent)
{
if(exponent >= current_degree)
reserve(exponent);
coef[exponent] = coefficient;
size++;
}

void polynomial::reserve(unsigned int number)
{
double new_poly;

if(number == current_degree)
return;
if(number < size)
number = size;

new_poly = new double[number];
for(int i = 0; i < size; i++)
new_poly[i] = coef[i];

delete[] coef;
coef = new_poly;
current_degree = number;
}

double polynomial::coefficient(unsigned int exponent)const
{
return (coef[exponent]);
}

double polynomial::eval(double x)const
{
size_t i = 0;

for(i = 1; i< size; i++)

}

polynomial operator+(const polynomial & p1, const polynomial & p2)
{
polynomial t;

if (size !=0)
{
reserve(p1.size);
t.coefficient = p1.coefficient;
for(int i = 0; i > p2.size; i--)
t.coefficient[i] += p2.coefficient[i];
}
else
{
reserve(p2.size);
t.coefficient = p2.coefficient;
for(int i = 0; i < p1.size; i++)
t.coefficient[i] += p1.coefficient[i];
}

return t;
}

polynomial operator-(const polynomial & p1, const polynomial & p2)
{
return p1 + (-1 * p2);
}

ostream & operator<<(ostream & out, const polynomial & p)
{
size_t i = 0;

if(size != 0)
{
out << "The Polynomial is: " << size << endl;
for(i = size - 1; i > 0; i--)
{/*125*/
cout << coef[i] << "x^" << i;
if(i != 0)
cout << "+";
}
if (i == 0)
cout << coef[0] << endl;
}
else
out << "Sorry no polynomials" << endl;

return out;
}

// FILE: poly.h
// CLASS PROVIDED:
//   class polynomial
//     A polynomial has one variable x, real number coefficients, and
//     non-negative integer exponents. Such a polynomial can be viewed
//     as having the form:
//       A[n]*x^n + A[n-1]*x^(n-1) + ... A[2]*x^2 + A[1]*x + A[0]
//     where the A[n] are the real number coefficients and x^i represents
//     the variable x raised to the i power. The coefficient A[0] is
//     called the "constant" or "zeroth" term of the polynomial.

//   1. This version works by storing the coefficients in
//      a dynamic array. The coefficient for the x^k term is stored
//      in location [k] of the dynamic array. When a new term is
//      added beyond the current size of the array, then the
//      dynamic array is replaced by a new, larger array.
//   2. Note that one function has been implemented as inline functions
//      in this file (the degree function).

// MEMBER CONSTANTS
//   const size_t DEFAULT_CAPACITY
//     The size of the initial array to store the coefficients.
//
// CONSTRUCTOR for the polynomial class
//     POSTCONDITION: This polynomial has been create with all zero
//     coefficients, except for coefficient c for the specified exponent.
//     When used as a default constructor (using default values for
//     both arguments), the result is a polynomial with all zero
//     coefficients.

// MODIFICATION MEMBER FUNCTIONS for the polynomial class
//   void assign_coef(double coefficient, unsigned int exponent)
//     POSTCONDITION: Sets the coefficient for the specified exponent.
//
//   void reserve(unsigned int number)
//     POSTCONDITION: The size of the array for coefficients has been changed
//     to the requested number (but not less that the size needed to store the
//     current non-zero coefficients). In effect, this guarantees that member
//     functions will not need to allocate new memory for exponents through

// CONSTANT MEMBER FUNCTIONS for the polynomial class
//   double coefficient(unsigned int exponent) const
//     POSTCONDITION: Returns coefficient at specified exponent of this
//     polynomial.
//
//   unsigned int degree( ) const
//     POSTCONDITION: The function returns the value of the largest exponent
//     with a non-zero coefficient.
//     If all coefficients are zero, then the function returns zero.
//
// NON-MEMBER BINARY OPERATORS for the polynomial Class
//   polynomial operator -(const polynomial& p1, const polynomial& p2)
//     POSTCONDITION: return-value is a polynomial with each coefficient
//     equal to the difference of the coefficients of p1 & p2 for any given
//     exponent.
//
//   polynomial operator +(const polynomial& p1, const polynomial& p2)
//     POSTCONDITION: return-value is a polynomial with each coefficient
//     equal to the sum of the coefficients of p1 & p2 for any given
//     exponent.
//
// NON-MEMBER OUTPUT FUNCTIONS for the polynomial Class
//   ostream& operator << (ostream& out, const polynomial& p)
//     POSTCONDITION: The polynomial has been printed to ostream out, which,
//     in turn, has been returned to the calling function.
//
// DYNAMIC MEMORY
//   Since this class uses dynamic memory, the copy constructor and assignment
//   operator are overridden, and there is a destructor implemented.

#ifndef POLY_H
#define POLY_H
#include <iostream>  // Provides ostream

using namespace std;

const unsigned int DEFAULT_CAPACITY = 30;

class polynomial
{

public:
// CONSTRUCTORS and DESTRUCTOR
polynomial(double c = 0.0, unsigned int exponent = 0);
polynomial(const polynomial& source);
~polynomial( ){delete[] coef;}

// MODIFICATION MEMBER FUNCTIONS
void operator =(const polynomial& source);
void assign_coef(double coefficient, unsigned int exponent);
void reserve(unsigned int number);
void setcurrent_degree(int init_degree) {current_degree = init_degree;}

// CONSTANT MEMBER FUNCTIONS
double coefficient(unsigned int exponent) const;
unsigned int degree( ) const { return current_degree; }
double eval(double x) const;

private:
double *coef;                 // Pointer to the dynamic array
unsigned int size;            // Current size of the dynamic array
unsigned int current_degree;  // Current degree of the polynomial
};

// NON-MEMBER FUNCTIONS
ostream& operator << (ostream& out, const polynomial& p);
polynomial operator +(const polynomial& p1, const polynomial& p2);
polynomial operator -(const polynomial& p1, const polynomial& p2);

#endif

0
Question by:supers4972

LVL 8

Expert Comment

ID: 8067055
>> The functions reserve, eval and addition keep are where the bulk of my errors coming up

What errors?

Exceter
0

LVL 2

Accepted Solution

constructor earned 300 total points
ID: 8068003
The compilation errors are not the bad ones, I'm afraid. The logical ones are far worse. Here's my thoughts about your code. The list is not complete and some of it is just suggestions.

Don't write "using namespace std" in the header. This way you force users of the class to either dump everything into global namespace or to define an encapsulating namespace themselves. Just tolerate the few std:: that will occur in the header.

Make the default size a part of the class, an enumeration will do fine and it doesn't cost anything.

Make constructors (except copy constructor) explicit.

You forgot to define/implement the default constructor!

Don't allow a function like setcurrent_degree to be public! It's an ugly and potentially dangerous way to let the user manipulate the internal data. What if they specify a larger degree than the current internal allocated size?

In the copy assignement (operator =), isn't it enough to ensure that size>=source.size or size>=source.degree? Allocations are quite costly.

Error in reserve, "double new_poly;" should be "double *new_poly;".

******************************************************

The worst errors are the logical errors in assign_coef and reserve, so this is where you need to focus your work!
Personally, I think that you split the responsibility
in an awry fashion between the two. Reserve should only consider memory operations and assign_coef should set the remaining data right.

There are some invariants that your polynomial object must satisfy in order to be in a consistent state:
1) The member size must always be larger than current_degree.
2) current_degree must indicate the largest exponent for which the coefficient is non-zero.

Memory:
Whence, if the user assigns to a coefficient that exists (<size), there is no need to reserve.
If the user assigns to a coefficient that doesn't exist (>=size), more memory should be reserved IF the coefficient is non-zero.

Remaining:
If the power of the assigned coefficient is larger or equal to the current degree, then current degree should be recalculated (private method). This catches assignments of the highest power coefficient to zero as well as introduction of yet higher powers.

******************************************************

Beware of returning coefficients that are not there (if user specifies an i>size in the method coefficient), or you will get a segmentation fault.

Skip the <cmath> header as you don't need pow (you can do faster without it). The eval method should read something like:

double polynomial::eval(double x) const
{
if(current_degree==0)
return coef[0];
unsigned int i=current_degree;
while(i-->0U)
}

Your non-member operators obviously needs a lot of work yet. The arithmetic ones can be implemented in very simple ways, if you implement suitably methods for the class first, for example unary +/-, then += and -=.
The stream operation is just a matter of formatting, but remember that you must read information from the polynomial through its interface.

For the sake of completeness, shouldn't unary +/-, binary *, /, %, operator assignments (+= etc) and >> operators be defined as well?

For a more fancy notation, you could use P[i] to get and set the i'th coefficient of the polynomial (instead of assign_coef and coefficient) and P(x) to evaluate it at a point (instead of eval).

Make it a template to allow other types than double (complex fx).

Hope you make sense of some of it :)
0

Author Comment

ID: 8069572
Here are my errors. I know it would be nice if I could use other operatior but the project calls to only use the ones that are listed.

D:\School\Data Structures\Project 2\Poly.cpp(64) : error C2440: '=' : cannot convert from 'double *' to 'double'
There is no context in which this conversion is possible
D:\School\Data Structures\Project 2\Poly.cpp(66) : error C2109: subscript requires array or pointer type
D:\School\Data Structures\Project 2\Poly.cpp(66) : error C2106: '=' : left operand must be l-value
D:\School\Data Structures\Project 2\Poly.cpp(69) : error C2440: '=' : cannot convert from 'double' to 'double *'
There is no context in which this conversion is possible
D:\School\Data Structures\Project 2\Poly.cpp(83) : error C2440: '=' : cannot convert from 'double *const ' to 'double'
There is no context in which this conversion is possible
D:\School\Data Structures\Project 2\Poly.cpp(94) : error C2065: 'size' : undeclared identifier
D:\School\Data Structures\Project 2\Poly.cpp(96) : error C2065: 'reserve' : undeclared identifier
D:\School\Data Structures\Project 2\Poly.cpp(96) : error C2248: 'size' : cannot access private member declared in class 'polynomial'
d:\school\data structures\project 2\poly.h(101) : see declaration of 'size'
D:\School\Data Structures\Project 2\Poly.cpp(97) : error C2659: '=' : overloaded function as left operand
D:\School\Data Structures\Project 2\Poly.cpp(98) : error C2248: 'size' : cannot access private member declared in class 'polynomial'
d:\school\data structures\project 2\poly.h(101) : see declaration of 'size'
D:\School\Data Structures\Project 2\Poly.cpp(99) : error C2109: subscript requires array or pointer type
D:\School\Data Structures\Project 2\Poly.cpp(99) : error C2109: subscript requires array or pointer type
D:\School\Data Structures\Project 2\Poly.cpp(99) : error C2296: '+=' : illegal, left operand has type 'double (__thiscall polynomial::*)(unsigned int) const'
D:\School\Data Structures\Project 2\Poly.cpp(99) : error C2297: '+=' : illegal, right operand has type 'double (__thiscall polynomial::*)(unsigned int) const'
D:\School\Data Structures\Project 2\Poly.cpp(103) : error C2248: 'size' : cannot access private member declared in class 'polynomial'
d:\school\data structures\project 2\poly.h(101) : see declaration of 'size'
D:\School\Data Structures\Project 2\Poly.cpp(104) : error C2659: '=' : overloaded function as left operand
D:\School\Data Structures\Project 2\Poly.cpp(105) : error C2248: 'size' : cannot access private member declared in class 'polynomial'
d:\school\data structures\project 2\poly.h(101) : see declaration of 'size'
D:\School\Data Structures\Project 2\Poly.cpp(106) : error C2109: subscript requires array or pointer type
D:\School\Data Structures\Project 2\Poly.cpp(106) : error C2109: subscript requires array or pointer type
D:\School\Data Structures\Project 2\Poly.cpp(106) : error C2296: '+=' : illegal, left operand has type 'double (__thiscall polynomial::*)(unsigned int) const'
D:\School\Data Structures\Project 2\Poly.cpp(106) : error C2297: '+=' : illegal, right operand has type 'double (__thiscall polynomial::*)(unsigned int) const'
D:\School\Data Structures\Project 2\Poly.cpp(114) : error C2677: binary '*' : no global operator defined which takes type 'const class polynomial' (or there is no acceptable conversion)
D:\School\Data Structures\Project 2\Poly.cpp(126) : error C2065: 'coef' : undeclared identifier
D:\School\Data Structures\Project 2\Poly.cpp(126) : error C2109: subscript requires array or pointer type
D:\School\Data Structures\Project 2\Poly.cpp(131) : error C2109: subscript requires array or pointer type
Error executing cl.exe.
0

LVL 11

Expert Comment

ID: 9888119
No comment has been added lately, so it's time to clean up this TA. I will
leave a recommendation in the Cleanup topic area that this question is:

Experts: Silence means you don't care. Grading recommendations are made in light
of the posted grading guidlines (http://www.experts-exchange.com/help.jsp#hi73).

EE Cleanup Volunteer
0

Featured Post

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
Suggested Courses
Course of the Month13 days, 13 hours left to enroll