title: Polynomial Operations
body: <p>I am trying to write a program that constructs a polynomial from an input file. It reads in the polynomial and stores values into the class attributes "coefficient" and "exponent". E.g. coefficient = 2, exponent = 3 would result in 2x^3. There are a lot of annoying corner cases that must be handled when reading in the polynomial and outputting. (<code>operator&lt;&lt;</code> and <code>operator&gt;&gt;</code> functions) My main function thoroughly tests my polynomial.cpp. I believe one of my problems is coming from constructing the polynomial and as you may note, I'm also having trouble writing code for my derive function. Here is what I have:</p>
  
  <pre><code>#ifndef _POLYNOMIAL_H
  #define _POLYNOMIAL_H
  
  #include &lt;iostream&gt;
  #include &lt;vector&gt;
  #include &lt;sstream&gt;
  
  using namespace std;
  
  class Polynomial {
  
   public:
  
    Polynomial();
    Polynomial(vector&lt;double&gt; iCoefficients, vector&lt;int&gt; iExponents);
  
    int Degree() const;
    double Evaluate(double x) const;
    Polynomial Derivative() const;
  
    friend Polynomial operator+(const Polynomial &amp; p, const Polynomial &amp; p2);
    friend Polynomial operator*(const Polynomial &amp; p, const Polynomial &amp; p2);
    friend ostream&amp; operator&lt;&lt;(ostream&amp; out, const Polynomial &amp; p);
    friend istream&amp; operator&gt;&gt;(istream&amp; in, Polynomial &amp; p);
  
   private:
  
    vector&lt;double&gt; coefficients;
  
  };
  #endif
  
  #include "polynomial.h"
  #include &lt;stdexcept&gt;
  #include &lt;vector&gt;
  #include &lt;cmath&gt;
  
  using namespace std;
  
  // Default Constructor
  Polynomial::Polynomial() { 
    coefficients.push_back(0);
  }
  
  // Constructor for a Polynomial
  Polynomial::Polynomial(vector&lt;double&gt; iCoefficients, vector&lt;int&gt; iExponents) { 
  
    for (int i = 0; i &lt; iExponents[0]; i++) {
      coefficients.push_back(0);
    }
  
    for (size_t i = 0; i &lt; iExponents.size(); i++) {
      coefficients[(Degree() - iExponents[i])] = iCoefficients[i];
     }
   }
  
  // Returns highest exponent of the polynomial
  int Polynomial::Degree() const { 
  
    return coefficients.size();
  }
  
  // Evaluates the polynomial at a particular point
  double Polynomial::Evaluate(double x) const { 
  
    double result;
  
    for(int i = 0; i &lt;= Degree(); i++) {
      result += pow(x, Degree() - i) * coefficients[i];
    }
    return result;
  }
  
  // Returns first derivative of the polynomial
  Polynomial Polynomial::Derivative() const { //----------------------???
  
  //   Polynomial result;
  
  //   for(int i = 0; i &lt;= Degree(); i++) {
  //     result.coefficients[i] = coefficients[i] * (Degree() - i);
  //   }
  //   return result;
  }         
  
  
  // Returns polynomial object that is the sum of parameters
  Polynomial operator+(const Polynomial &amp; p, const Polynomial &amp; p2) { 
  
    int d = p.Degree();
    int d2 = p2.Degree();
    Polynomial sum;
  
    for (int j = 0; j &lt; d; j++) {
      for (int i = 0; i &lt; d2; i ++) {
        sum.coefficients.push_back(p.coefficients[j] + p2.coefficients[i]);
      }
    }
    return sum;
  }
  
  // Returns polynomial object that is the product of parameters
  Polynomial operator*(const Polynomial &amp; p, const Polynomial &amp; p2) {
  
    int d = p.Degree();
    int d2 = p2.Degree();
    Polynomial product;
  
    for (int j = 0; j &lt; d; j++) {
      for (int i = 0; i &lt; d2; i ++) {
        product.coefficients.push_back(p.coefficients[j] * p2.coefficients[i]);
      }
    }
    return product;
  }
  
  // Output operator
  ostream&amp; operator&lt;&lt;(ostream&amp; out, const Polynomial &amp; p) {
  
    for (int i = 0; i &lt;= p.Degree(); i++) {
  
      if(i == 0 &amp;&amp; p.Degree() &lt;= 1) {
        out &lt;&lt; 0;
      }
  
      if (p.coefficients[i] != 0 &amp;&amp; i != 0) {
        out &lt;&lt; '+';
      }
  
      if (p.coefficients[i] != 0) {
        out &lt;&lt; p.coefficients[i];
        if(i &lt; (p.Degree() - 1)) {
      out &lt;&lt; "x^";
      out &lt;&lt; (i - p.Degree()) * (-1);
        }
      }
    }
    return out;
  }
  
  // Input operator
  istream&amp; operator&gt;&gt;(istream&amp; in, Polynomial &amp; p) {
  
    char ch;
    int exponent;
    double coefficient;
    vector&lt;double&gt; coefficients;
    vector&lt;int&gt; exponents;
  
    while(isspace(ch) == false) {
  
      ch = in.peek();
      if(ch == '+') {
        in.ignore();
        in &gt;&gt; coefficient;
      }
      else if(ch == '-') {
        in.ignore();
        in &gt;&gt; coefficient;
        coefficient = coefficient * (-1);
      }
      else {
        in &gt;&gt; coefficient;
      }
        ch = in.peek();
        if((ch &lt;= 'z') &amp;&amp; (ch &gt;= 'a')) {
      in &gt;&gt; ch;
      ch = in.peek();
        if(ch == '^') {
          in.ignore();
          in &gt;&gt; exponent;
        }
        else 
          exponent = 1;
        }
        else
      exponent = 0;
  
        coefficients.push_back(coefficient);
        exponents.push_back(exponent);
    } 
  
    p = Polynomial(coefficients, exponents);
  
    return in;
  }
  
  #include &lt;iostream&gt;
  #include &lt;sstream&gt;
  #include &lt;string&gt;
  #include &lt;cmath&gt;
  #include "polynomial.h"
  
  using namespace std;
  
  bool testPolynomial(const Polynomial&amp; p, string expected);
  bool testOperations(const Polynomial&amp; p, int degree, double expected);
  bool testInput(string s);
  
  
  int main() {
    int errors = 0;
  
    cerr &lt;&lt; "Note: Nearly all of the tests expect a working output operator. If a test fails, check that first" &lt;&lt; endl;
    cerr &lt;&lt; "Testing default constructor" &lt;&lt; endl;
    Polynomial p1;   // test default constructor
    errors += testPolynomial(p1, "0");
  
    cerr &lt;&lt; "Testing explicit value constructor" &lt;&lt; endl;
    double c_arr[] =  {1.1, 2, 4, 7};
    int e_arr[] = {6, 3, 2, 0};
    vector&lt;double&gt; c(c_arr, c_arr+4);
    vector&lt;int&gt; e(e_arr, e_arr+4);
    Polynomial p2(c, e);
    errors += testPolynomial(p2, "1.1x^6+2x^3+4x^2+7");
    c.clear(); e.clear();
    cout &lt;&lt; '1' &lt;&lt; endl;
    Polynomial p3(c, e);
    errors += testPolynomial(p3, "0");
    cout &lt;&lt; '2' &lt;&lt; endl;
  
    cerr &lt;&lt; "Testing operations" &lt;&lt; endl;
    double c2_arr[] =  {-1.1, 2, -4, 7};
    int e2_arr[] = {4, 3, 2, 0};
    vector&lt;double&gt; c2(c2_arr, c2_arr+4);
    vector&lt;int&gt; e2(e2_arr, e2_arr+4);
    Polynomial p4(c2,e2);
    errors += testOperations(p1, 0, 0);
    errors += testOperations(p2, 6, 109.4);
    errors += testOperations(p4, 4, -10.6);
  
    errors += testPolynomial(p1.Derivative(), "0");
    errors += testPolynomial(p2.Derivative(), "6.6x^5+6x^2+8x");
    errors += testPolynomial(p4.Derivative(), "-4.4x^3+6x^2-8x");
  
    errors += testPolynomial(p1+p2, "1.1x^6+2x^3+4x^2+7");
    errors += testPolynomial(p2+p4, "1.1x^6-1.1x^4+4x^3+14");
  
    errors += testPolynomial(p1*p2, "0");
    errors += testPolynomial(p2*p2, "1.21x^12+4.4x^9+8.8x^8+19.4x^6+16x^5+16x^4+28x^3+56x^2+49");
    double c_arr3[] = {-1};
    int e_arr3[] = {0};
    vector&lt;double&gt; c3 = vector&lt;double&gt;(c_arr3, c_arr3+1);
    vector&lt;int&gt; e3 = vector&lt;int&gt;(e_arr3, e_arr3+1);
    Polynomial p5(c3, e3);
  
    errors += testPolynomial(p2 * p5 + p2, "0");
    errors += testPolynomial(p5, "-1");
  
    cerr &lt;&lt; "Testing input operator." &lt;&lt; endl;
    testInput("0");
    testInput("51");
    testInput("-1.1");
    testInput("3x^2");
    testInput("-5x^3-5");
    testInput("x^5+x-1");
    testInput("-x^4+2");
  
    return errors;
  }
  
  bool testPolynomial(const Polynomial&amp; p, string expected) {
    ostringstream out;
    out &lt;&lt; p;
    if (out.str() != expected) {
      cerr &lt;&lt; "Test failed: expected " &lt;&lt; expected &lt;&lt; " got " &lt;&lt; out.str() &lt;&lt; endl;
      return true;
    } else {
      return false;
    }
  }
  
  bool testOperations(const Polynomial&amp; p, int degree, double expected) {
    if(p.Degree() != degree) {
      cerr &lt;&lt; "Failed Degree operation" &lt;&lt; endl;
      return true;
    }
    double result = p.Evaluate(2.0);
    if (fabs(result - expected) &gt; 1e-5) {
      cerr &lt;&lt; "Failed Evaluation operation" &lt;&lt; endl;
    }
    return false;
  }
  
  bool testInput(string s) {
    Polynomial p;
    istringstream in(s+" ");
    in &gt;&gt; p;
    ostringstream out;
    out &lt;&lt; p;
    if (out.str() != s) {
      cerr &lt;&lt; "Failed input test. Expected: " &lt;&lt; s &lt;&lt; " got " &lt;&lt; out.str() &lt;&lt; endl;
      return true;
    }
    return false;
  }
  </code></pre>