?
Solved

Need help with Polynomial class

Posted on 2003-03-04
5
Medium Priority
?
1,085 Views
Last Modified: 2012-05-04
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;
      double answer = 0.0;
      
      answer = coef;
      for(i = 1; i< size; i++)
            answer = answer +(coef[i] * pow(x,i));

      return answer;
}

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
Comment
Question by:supers4972
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
5 Comments
 
LVL 8

Expert Comment

by:Exceter
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

by:
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];
     double answer=coef[current_degree];
     unsigned int i=current_degree;
     while(i-->0U)
          answer=answer*x+coef[i];
          return answer;
}

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

by:supers4972
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

by:bcladd
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:

Answered: Points to constructor: Grade A

Please leave any comments here within the next seven days.

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).

PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

-bcl (bcladd)
EE Cleanup Volunteer
0

Featured Post

Want to be a Web Developer? Get Certified Today!

Enroll in the Certified Web Development Professional course package to learn HTML, Javascript, and PHP. Build a solid foundation to work toward your dream job!

Question has a verified solution.

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

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
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 pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

766 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question