My project is to create a polynomial with rational coeffients. I am stuck at this point with 2 error messages, one being "illegal indirection" in "function operato<<" . I think that my constructors are not correct. Deadline is fast-approaching. Any help would be appreciated.

class Polynomial
{
	int *coeff;
	int nCoeff;

public:
		
	Polynomial(const int = 0);
	Polynomial(Polynomial &);
	Polynomial(const int, int *);
	~Polynomial();

	const int getDegree();
	void shrink();
	int evaluate(int);

	Polynomial operator+( const Polynomial & ) const; // addition
	Polynomial operator-( const Polynomial & ) const; // subtraction
	Polynomial operator*( const Polynomial & ) const; // multiplication
	Polynomial& operator=(const Polynomial &a); 
	int operator[](unsigned int index);
	friend bool operator==(const Polynomial &, const Polynomial &);
	Polynomial& operator++(){
		++coeff[0];
		return *this;
	}
	Polynomial& operator++(int unused){
		++coeff[0];
		return *this;
	}
};
class RationalNumber
{
	Polynomial *n;
	Polynomial *d;
    public:

		
    RationalNumber( int = 0, int = 1); // constructor
	RationalNumber(Polynomial&);

	~RationalNumber();
    RationalNumber operator+( const RationalNumber& ) const; // addition
    RationalNumber operator-( const RationalNumber& ) const; // subtraction
    RationalNumber operator*( const RationalNumber& ) const; // multiplication
    RationalNumber operator/( const RationalNumber& ) const; // division

    // relational operators
    bool operator>( const RationalNumber& ) const; // greater than
    bool operator<( const RationalNumber& ) const; // less than
    bool operator>=( const RationalNumber& ) const; // greater than or equal to
    bool operator<=( const RationalNumber& ) const; // less than or equal to

    // equality operators
    bool operator==( const RationalNumber & ) const; // equality operator
    // inequality operator    
    bool operator!=( const RationalNumber &right ) const;
	friend ostream& operator<< (ostream&, RationalNumber&); // output
    

    void printRational() const; // display rational number
    
	private:
    int numerator; // private variable numerator
    int denominator; // private variable denominator
	void reduction(); // function for fraction reduction
	int gcd( int a, int b )const;

    }; // end class RationalNumber

// Polynomial constructor
Polynomial::Polynomial(const int a){
	coeff = new int[1];
	coeff[0] = a;
	nCoeff = 1;
}
Polynomial::Polynomial(const int a, int *c){
	nCoeff = a + 1;
	coeff = new int[a+1];

	for (int i = 0;i < (a+1); ++i){
		coeff[i] = c[i];
	}
}
Polynomial::Polynomial(Polynomial &p){
	if (this != &p){
		if(nCoeff >= 0) delete []coeff;
		int size = p.getDegree();
		coeff = new int[size+1];
		for (int i = 0; i <= size; ++i) coeff[i] = p.coeff[i];
		nCoeff = p.nCoeff;
	}
}
Polynomial::~Polynomial(){
	delete[]coeff;
}
const int Polynomial::getDegree(){
	int i = nCoeff - 1;
	while (coeff[i] == 0) --i;
	return (i >= 0) ? i : 0;
}
void Polynomial::shrink(){
	int i = getDegree();
	while(coeff[i] == 0) --i;
	int *temp = new int[i+1];
	for (int j = 0; j <= i; ++j) temp[j] = coeff[j];

	if (i < 0){
		coeff = new int[1];
		coeff[0] = 0;
		nCoeff = 0;
	}else{
		coeff = new int[i+1];
		for (int j = 0; j <= i; ++j) coeff[j] = temp[j];
	}
}

int Polynomial::evaluate(int a){
	double result = 0;
	for (int i = 0; i < nCoeff; ++i) result += coeff[i] * pow((double)a,
		(double)i);
		return (int)result;
}
 
    // RationalNumber constructor
    RationalNumber::RationalNumber( int n, int d )
    {
		if (d == 0) {
			denominator = 1;
			numerator = 0;
	} else if ( d < 0 )	{
		denominator = -d;
		numerator = -n;
		} else {
			denominator = d;
			numerator = n;
		}
	reduction();
	}
	
	RationalNumber::~RationalNumber()
	{
	}
	
	// returns greatest common divisor 
	int RationalNumber::gcd(int a, int b)const{
		int temp = 0;

		if ( a == 0)
			return b;
		else if (b == 0)
			return a;
		else if (a < b)
		{
			temp = b;
			b = a;
			a = temp;
			return (gcd(b, a% b));
		}
		else
			return (gcd(b, a% b));

	} // end funtion gcd

	// overloaded + operator
	RationalNumber RationalNumber::operator+( const RationalNumber &operand2 ) const
	{
		RationalNumber t;

		t.numerator = numerator * operand2.denominator; // (ad)
		t.numerator += denominator * operand2.numerator; // (ad + bc)
		t.denominator = denominator * operand2.denominator; // formula (ad + bc)/(bd)
		t.reduction();
		return t;
	}
	// overloaded - operator
    
	RationalNumber RationalNumber::operator-( const RationalNumber &operand2 ) const
	{
		RationalNumber t;

		t.numerator = numerator * operand2.denominator; // (ad)
		t.numerator -= denominator * operand2.numerator; // (ad - bc)
		t.denominator = denominator * operand2.denominator;//formula (ad - bc)/(bd)
		t.reduction();
		return t;
	}
	// overloaded * operator
	RationalNumber RationalNumber::operator*( const RationalNumber &operand2 ) const
	{
		RationalNumber t;

		t.numerator = numerator * operand2.numerator; // (ac)
		t.denominator = denominator * operand2.denominator; // formula (ac)/(bd)   
		t.reduction();
		return t;
	}
	// overloaded / operator
	RationalNumber RationalNumber::operator/( const RationalNumber &operand2 ) const
	{
		RationalNumber t;

		t.numerator = numerator * operand2.denominator;// (ad)
		t.denominator = denominator * operand2.numerator; // formula (ad)/(bc)
		t.reduction();
		return t;
	}
	// overloaded > operator
	bool RationalNumber::operator>( RationalNumber const &operand2 ) const
	{
		return (( numerator*operand2.denominator) > (denominator*operand2.numerator));
	}
	// overloaded < operator
	bool RationalNumber::operator<( RationalNumber const &operand2 ) const
	{
		return (( numerator*operand2.denominator) < (denominator*operand2.numerator));
	}
	// overloaded >= operator
	bool RationalNumber::operator>=( RationalNumber const& operand2 ) const
	{
		return (( numerator*operand2.denominator) >= (denominator*operand2.numerator));
	}
    // overloaded <= operator
	bool RationalNumber::operator<=( RationalNumber const &operand2 ) const
	{
		return (( numerator*operand2.denominator) <= (denominator*operand2.numerator));
	}
   // overloaded == operator
	bool RationalNumber::operator==( RationalNumber const& operand2 ) const
	{
		return (( numerator*operand2.denominator) == (denominator*operand2.numerator));
	}
   // overloaded != operator
	bool RationalNumber::operator!=( RationalNumber const &operand2 ) const
	{
		return !( *this == operand2 );
	}
    // function printRational definition

	ostream& operator<< (ostream& out, RationalNumber& r)
	{
		Polynomial *zero = new Polynomial(0);
		if (*(r.n) == *zero){
			out << "0";
		}else{
			out << *(r.n);
			out << " / ";
			out << *(r.d);
		}
		
		return out;
	}


	void RationalNumber::printRational() const
	{
	    if ( numerator == 0 ) // print fraction as zero
		    cout << numerator;
		else if ( denominator == 1 ) // print fraction as integer
            cout << numerator;
		else
		cout << numerator << '/' << denominator;
    } // end function printRational definition
	// function reduction definition
	void RationalNumber::reduction()
		{
			int factor = gcd(numerator, denominator);
			numerator = numerator / factor;
			denominator = denominator / factor;
	} // end function reduction

Recommended Answers

All 17 Replies

EDIT: Ignore the other part about ostream. Since n and d are private members, you must access them through some kind of "getter" function. If they were public you'd probably want something more like r.(*n) instead of the way you have it (you can't dereference r as it is not a pointer).

Do you have ostream qualified with std:: (or perhaps, though less preferred, have a using namespace std; )? It doesn't look like you have iostream included but I'm assuming you clipped off the top of the file. Possibly obvious things I realize but just in case.

Yes I do.

#include <cstdlib>
#include <iostream>
#include<math.h>
using namespace std;

I went back and looked it over again. I edited my post but you got there first.

This also means you'll need to overload << for your poly class.

I think that I have too much extra in this code. I'm trying to figure out a way to eliminate some of the functions that I might not need. Basically what I need to do is implement a polynomial that has rational coefficients. I have created two separate codes; one with rational coefficients and another just with a polynomial. Now, how to bring the two together?

I think that I have too much extra in this code. I'm trying to figure out a way to eliminate some of the functions that I might not need. Basically what I need to do is implement a polynomial that has rational coefficients. I have created two separate codes; one with rational coefficients and another just with a polynomial. Now, how to bring the two together?

My approach is always (well, not always) this: Get the constructors right first. Then do the << operator. Then the >> operator. Then the == operator. Then the + and - operators. Then maybe some of the inequality operators, then the * and / operators.

But I always do the << operator as soon as possible since I need that one and I might as well have it so I can get some output, which helps when I am working on the rest of it. Thus I would get rid of all the other operators for now, shorten the code, and that makes it more manageable. Generally I also tend to recommend, if one is not used to or rusty passing streams, that you write a PrintIt () function that displays to the screen first, then do your << operator after THAT works. That lets you fix any this-> versus this. errors and stuff like that. THEN you write a function that does the same,e xcept that you pass it a stream, THEN you write the << operator.

Tedious, and something you can skip when you get more experience, but it really helps you work in an orderly process and makes you figure out exactly what the problem is. In addition, I sometimes make everything public first, get THAT working, then make them private or protected or whatever and get the "friend" stuff working.

Break it into steps. You are tackling too much at once.

Don't you want something like this:

class Rational
{
   int num;
   int denom;
   etc
};

class Polynomial
{
    Rational coefficients*;
};

Your version creates a rational number using 2 polynomials, which is legal, but it isn't creating polynomials with rational coefficients. I think you want to be able to do something like this

(1/2)x^2 + (3/11)x - (43/57)

rather than something like this:

(3x^2 -1)/(4x + 6);

commented: Yeah, I was thinking along that same lines... +4

Well, at this point I am completely baffled about how to proceed. Should I create two seperate classes? Any advice would be apprectiated.

Yes, you will need need two separate classes, Rational and Polynomial, but first determine what you are trying to do: use a class to model rational numbers that has polynomials for numerator and denominator, or, use rational numbers for coefficients in polynomials. If it's the former, then you can continue with the classes you have. If it's the latter then you should declare the classes more along the lines that I posted in my first post. I base my posts on the first line of you first post.

With relatively few changes you can convert your posted version to something along the lines I've posted. You will probalby want all of the functionality you've already created, and more. In my version you will want to be able to add and multipy two Rational numbers to add two Polynomials with Rational coefficients and you will should probably find the lowest common denominator so you can simplify the sum. You will also want to be able to multiply two Rational numbers if you want to implement multiplication of two Polynomials. You probably wouldn't need the division operator or the relational operators for this project, but having them available for other projects would make the Rational class more versatile.

Basically, I'd take lines 34, 35 and 40 out of the Rational class. I'd declare the Rational class before the Polynomial class (or I'd include the Rational class in the Polynomial class if I were creating header and cpp files for the two classes). I'd redo the overloaded << operator for the Rational class----it should look a lot like the printRational() function except it should use out instead of cout, and, of course it needs to return out like you have it do already.

In the Polynomial class I'd change int in line 3 to Rational. I'd create a constructor and/or a acceptAsString() function to accept a string as user input representing the polynomial and parse it for the coefficients and exponents. I'd also let the user enter individual coeffients and exponents if they want by creating a setTerm function. Then once I had the full set of exponents and coefficients I'd determine the degree, if I didn't force the user to tell me ahead of time. The shrink() function would add like terms, (add coefficients of the terms with the same exponent) and the evaluate() function would need to have a value for x or a or whatever variable you use so the polynomial could be evaluated for x or a or whatever. I haven't taken the time to see if your posted implementations of shrink() and evaluate() seem reasonable or not, though a quick glance suggest that they may not be quite up to snuff (for example, why should a polynomial with rationaly coefficients be required to return an int. I could see returning a rational number or maybe even a double, but an int seems fishy as first blush). Finally, I'd overload the mathematical operators like +, - and * for the Polynomial class.

To be precise, I am implementing a polynomial class with rational coefficients.

Yes, you will need need two separate classes, Rational and Polynomial, but first determine what you are trying to do: use a class to model rational numbers that has polynomials for numerator and denominator, or, use rational numbers for coefficients in polynomials. If it's the former, then you can continue with the classes you have. If it's the latter then you should declare the classes more along the lines that I posted in my first post. I base my posts on the first line of you first post.

With relatively few changes you can convert your posted version to something along the lines I've posted. You will probalby want all of the functionality you've already created, and more. In my version you will want to be able to add and multipy two Rational numbers to add two Polynomials with Rational coefficients and you will should probably find the lowest common denominator so you can simplify the sum. You will also want to be able to multiply two Rational numbers if you want to implement multiplication of two Polynomials. You probably wouldn't need the division operator or the relational operators for this project, but having them available for other projects would make the Rational class more versatile.

Basically, I'd take lines 34, 35 and 40 out of the Rational class. I'd declare the Rational class before the Polynomial class (or I'd include the Rational class in the Polynomial class if I were creating header and cpp files for the two classes). I'd redo the overloaded << operator for the Rational class----it should look a lot like the printRational() function except it should use out instead of cout, and, of course it needs to return out like you have it do already.

In the Polynomial class I'd change int in line 3 to Rational. I'd create a constructor and/or a acceptAsString() function to accept a string as user input representing the polynomial and parse it for the coefficients and exponents. I'd also let the user enter individual coeffients and exponents if they want by creating a setTerm function. Then once I had the full set of exponents and coefficients I'd determine the degree, if I didn't force the user to tell me ahead of time. The shrink() function would add like terms, (add coefficients of the terms with the same exponent) and the evaluate() function would need to have a value for x or a or whatever variable you use so the polynomial could be evaluated for x or a or whatever. I haven't taken the time to see if your posted implementations of shrink() and evaluate() seem reasonable or not, though a quick glance suggest that they may not be quite up to snuff (for example, why should a polynomial with rationaly coefficients be required to return an int. I could see returning a rational number or maybe even a double, but an int seems fishy as first blush). Finally, I'd overload the mathematical operators like +, - and * for the Polynomial class.

Fine, my last post should help you adjust your code to get there.

Fine, my last post should help you adjust your code to get there.

I'm trying to follow your instructions, but it takes me a little time to keep up. I moved the rational class first and took out some of the lines that you specified. You said to make the << overload look like the print function. How do I do that exactly? Thanks.

class RationalNumber
{
	
    public:

		
    RationalNumber( int = 0, int = 1); // constructor
	

	~RationalNumber();
    RationalNumber operator+( const RationalNumber& ) const; // addition
    RationalNumber operator-( const RationalNumber& ) const; // subtraction
    RationalNumber operator*( const RationalNumber& ) const; // multiplication
    RationalNumber operator/( const RationalNumber& ) const; // division

    // relational operators
    bool operator>( const RationalNumber& ) const; // greater than
    bool operator<( const RationalNumber& ) const; // less than
    bool operator>=( const RationalNumber& ) const; // greater than or equal to
    bool operator<=( const RationalNumber& ) const; // less than or equal to

    // equality operators
    bool operator==( const RationalNumber & ) const; // equality operator
    // inequality operator    
    bool operator!=( const RationalNumber &right ) const;
	friend ostream& operator<< (ostream&, RationalNumber&); // output
    

    void printRational() const; // display rational number
    
	private:
    int numerator; // private variable numerator
    int denominator; // private variable denominator
	void reduction(); // function for fraction reduction
	int gcd( int a, int b )const;

    }; // end class RationalNumber
//definition of operator<< based on printRational()
ostream & operator<<(ostream & out, const Rational & rhs)
{
        if (rhs.numerator == 0 ) 		    
             out << numerator;		
        else if ( denominator == 1 ) 
             out << numerator;	
        else		
              out << numerator << '/' << denominator;
 
        return out;
}

As long as << is declared as a friend then I believe << can access the private member variables, numerator and denominator, of rhs without using public accessor methods like getNumerator() and getDenominator(); though if the above doesn't work then add public accessor functions and call those on rhs rather than accessing the private member variables directly. Alternatively, while you are developing the project you can declare the member variables public and then go back and put in the accessor member functions as needed to make the initial functionality a little more developer friendly, though with public member variables the class less secure when the release version is ready to use, so having private member variables in the release version of the program is desireable.

BTW the syntax for line 7 post #12 looks off. Since its a simple constructor I'd consider replace that line with something like this:

RationalNumber(int n = 0, int d = 1) : numerator(n), denominator(d) {};

Damn Daniweb and and the fact that everything goes weird when you try to use a tab. Or damn me for trying to use tabs. Either way, I hit a tab and a return or whatever I did and lost a damn fine post! Oh well. I'll recreate part of it, but it won't be all of it.

class RationalNumber
{
    // code and stuff
    void printRational ();
    // more code and stuff, including operators.
};


class Polynomial
{
    // code and stuff
    RationalNumber* coefficients;
    int* degrees;
    int numTerms;
    // code and stuff
    void printPolynomial ();
};

Polynomial is going to involve RationalNumber. printPolynomial is going to call RationalNumber's printRational several times, numTerms times to be precise I would imagine.

I always like to order my terms high degree to low degree in my RationalNumber array, so the degree of the polynomial would be degrees[0].

printPolynomial is going to print every term, so set up a loop. Within the loop, call printRational, then display "x^", then display the term's degree. Between trems, have a '+' or '-' sign. Get RationalNumber working first since you need it for Polynomial. I'll reiterate my post 7. Do things in order, constructors and display functions first.

Does degrees really need to be an int pointer instead of just an int?

Does degrees really need to be an int pointer instead of just an int?

I was thinking it was an array of integers (size 3) and an array of Rational numbers (also size 3):

(8/3)x^6 + (3/2)x^3 + (7/8)x^1

In that case, degrees is a pointer to a 3-element int array {6,3,1}. If you include the zero coefficients, this would be a array of 7 Rational Numbers:

{8/3,0,0,3/2,0,7/8,0}

and the polynomial degree would be a single int (6 in this case).

I was assuming the first form (don't store the 0 coefficients), but perhaps the second form might be easier to implement (store the 0 coefficients).

>>I was assuming the first form (don't store the 0 coefficients), but perhaps the second form might be easier to implement (store the 0 coefficients).

And I was assuming the latter implementation, but your explanation of both was excellent. As you said, though, first the OP should complete a fully functional RationalNumbers class, and then they can decide on implementation options regarding the Polynomial class.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.