I am new in C++ and I have a problem with operator overloading. I just implemented the functions in the header file. I have completed the class as well but I cant get my main class to work. it doesn't send any output.
Please help my code is:
The header file:
class Fraction{
{
private:
int numerator;
int denominator;
public:
Fraction (int a=1, int b=1);
//declare Mutators
void setNumerator(int);
void setDenominator(int);
//declare Accessors
int getNumerator();
int getDenominator();
Fraction operator+(const Fraction &fra)const;
Fraction operator-(const Fraction &fra)const;
Fraction operator*(const Fraction &fra)const;
Fraction operator/(const Fraction &fra)const;
};
#endif /* FRACTION_H */
The Fraction.cpp
Fraction:: Fraction (int a,int b)
{
while (a<b && b<0)
{
if(b<0)
{
std:: cout<<"please enter a number grater then 0 in
denominator";
}
else
{
std:: cout<< "Please enter numerator greater then denominator";
}
}
numerator= a;
denominator= b;
}
void Fraction::setNumerator(int a)
{
numerator =a;
}
void Fraction::setDenominator(int a)
{
denominator =a;
}
// Operations
Fraction Fraction::operator-(const Fraction &f1)const
{
Fraction temp;
temp.numerator= (numerator*f1.denominator)-f1.numerator*denominator;
temp.denominator = denominator*f1.denominator;
for(int i = temp.numerator * temp.denominator ; i > 1; i--) //
{
if((temp.numerator % i == 0) && (temp. % i == 0))
{
{
temp.denominator /= i;
temp.numerator /= i;
}
}
}
return temp;
}
Fraction Fraction::operator+(const Fraction &f1)const
{
int a= (numerator*f1.denominator)+f1.numerator*denominator;
int b = denominator*f1.denominator;
for(int i = a * b ; i > 1; i--) //
{
if((a % i == 0) && (b % i == 0))
{
{
b /= i;
a /= i;
}
}
}
return Fraction(a,b);
}
Fraction Fraction::operator*(const Fraction &f1)const
{
int a= numerator *f1.numerator;
int b= denominator*f1.denominator;
for(int i = a * b ; i > 1; i--) //
{
if((a % i == 0) && (b % i == 0))
{
{
b /= i;
a /= i;
}
}
}
return Fraction(a,b);
}
Fraction Fraction::operator /(const Fraction& f1) const
{
int a= numerator *f1.denominator;
int b= denominator*f1.numerator;
for(int i = a * b ; i > 1; i--) //
{
if((a % i == 0) && (b % i == 0))
{
{
b /= i;
a /= i;
}
}
}
return Fraction(a,b);
}
std::ostream& operator<< (std::ostream &out, Fraction const& data) {
out << data.getDenominator() << ':';
out << data.getNumerator() << ':';
return out;
}
My main class so far is :
#include <iostream>
#include "fraction.h"
int main() {
Fraction f1(1,2);
std:: cout<<f1.getDenominator();
return 0;
}
I tryed to see if i can write my main but i had no luck on getting it.
Related
I find difficulties in this part because it takes the class objects as the parameter of the function:
friend Num_Fact GCD(Num_Fact , Num_Fact);
friend Num_Fact LCM(Num_Fact , Num_Fact);
How to implement the GCD function with arguments of 2 class objects, and return the value back in as Num_Fact as following in cpp:
cin >> value;
Num_Fact A(value);
cout << "Key in number B: ";
cin >> value;
Num_Fact B(value);
cout << " A = "<< A.output() <<" = "<<A.getnum()<<endl;
cout << " B = " <<B.output() << " = " << B.getnum() << endl;
Num_Fact C = GCD(A, B);
Original Code:
#ifndef NUM_FACTOR
#define NUM_FACTOR
#include<iostream>
#include<array>
#include<cmath>
#include<sstream>
using namespace std;
#define Z 20
class Num_Fact {
friend Num_Fact GCD(Num_Fact , Num_Fact);
friend Num_Fact LCM(Num_Fact , Num_Fact);
public:
Num_Fact(int num) {
Num = num;
}
~Num_Fact() {};
long long int findgcd(long long int a, int b) {
if (b == 0) return a;
return findgcd(b, a % b);
}
long long int LCM2(long long int a[], int n) {
long long int res = 1, i;
for (i = 0; i < n; i++) {
res = res * a[i] / findgcd(res, a[i]);
}
fact2num(res);
return res;
}
long long int GCD2(long long int arr[], int n)
{
long long int result = arr[0];
for (int i = 1; i < n; i++)
{
result = findgcd(arr[i], result);
if (result == 1)
{
fact2num(result);
return 1;
}
}
fact2num(result);
return result;
}
long long int GCD(int a, int b) {
int temp;
while (b != 0) {
temp = b;
b = a % b;
a = temp;
}
return a;
}
long long int LCM(int a, int b) {
int lcm = (a * b) / GCD(a, b);
return lcm;
}
string Factorize() {
ostringstream output;
int fac = 2;
if (Num == 1) {
output << Num;
}
while (Num > 1)
{
if (Num % fac == 0)
{
output << fac << "^"; //print the base first
Num /= fac;
int pow = 1;
while (Num % fac == 0) //get the power of current base
{
Num /= fac;
pow++;
}
output << pow; //print out the power, now we have fac^pow printed
//if not the last factor, print a multiplication symbol
if (Num != 1)
output << " * ";
}
else
{
fac++;
}
}
return output.str();
}
string output() {
ostringstream output;
output << Factorize();
return output.str();
}
int getnum() {
return Num;
}
private:
int Num;
array<array<int, Z>, 2>fact;
};
#endif
Latest code for Header:
#ifndef NUM_FACTOR
#define NUM_FACTOR
#include<iostream>
#include<array>
#include<cmath>
#include<sstream>
using namespace std;
#define Z 20
int findgcd(long long int a, int b) {
if (b == 0) return a;
return findgcd(b, a % b);
}
int LCM2(long long int a[], int n) {
int res = 1, i;
for (i = 0; i < n; i++) {
res = res * a[i] / findgcd(res, a[i]);
}
return res;
}
int GCD2(long long int arr[], int n)
{
int result = arr[0];
for (int i = 1; i < n; i++)
{
result = findgcd(arr[i], result);
if (result == 1)
{
return 1;
}
}
return result;
}
int GCD1(int a, int b) {
int temp;
while (b != 0) {
temp = b;
b = a % b;
a = temp;
}
return a;
}
int LCM(int a, int b) {
int lcm = (a * b) / GCD1(a, b);
return lcm;
}
class Num_Fact {
public:
Num_Fact(int num) {
Num = num;
}
~Num_Fact() {};
string Factorize() {
ostringstream output;
int fac = 2;
if (Num == 1) {
output << Num;
}
while (Num > 1)
{
if (Num % fac == 0)
{
output << fac << "^"; //print the base first
Num /= fac;
int pow = 1;
while (Num % fac == 0) //get the power of current base
{
Num /= fac;
pow++;
}
output << pow; //print out the power, now we have fac^pow printed
//if not the last factor, print a multiplication symbol
if (Num != 1)
output << " * ";
}
else
{
fac++;
}
}
return output.str();
}
string output() {
ostringstream output;
output << Factorize();
return output.str();
}
int getnum() {
return Num;
}
private:
int Num;
array<array<int, Z>, 2>fact;
};
Num_Fact GCD(Num_Fact A, Num_Fact B) {
return GCD(A.getnum(), B.getnum());
}
Num_Fact LCM(Num_Fact A, Num_Fact B) {
return LCM(A.getnum(), B.getnum());
}
#endif
Latest Code for CPP
#include<iostream>
#include<array>
#include<cmath>
#include<sstream>
#include"Num_Factor.h"
using namespace std;
const int S = 20;
void bonus();
int main() {
int value;
cout << "Key in number A: ";
cin >> value;
Num_Fact A(value);
cout << "Key in number B: ";
cin >> value;
Num_Fact B(value);
cout << " A = "<< A.output() <<" = "<<A.getnum()<<endl;
cout << " B = " <<B.output() << " = " << B.getnum() << endl;
Num_Fact C=GCD(A, B);
return 0;
}
It gives error when compiling such as "Unhandled exception at 0x00007FF72E1A53DF in lab09.exe: 0xC00000FD: Stack overflow (parameters: 0x0000000000000001, 0x000000C850A03EB8)." And also its pointing at:
Num_Fact GCD(Num_Fact A, Num_Fact B) {
return GCD(A.getnum(), B.getnum());
}
Num_Fact LCM(Num_Fact A, Num_Fact B) {
return LCM(A.getnum(), B.getnum());
}
The task is to call the Num_Fact C= GCD(A,B), the program is about to find gcd and lcm using classes and by using constructor such as "Num_Fact"
There's a lot of confusion in your class design. but I'm only going to address some of it here. First question, ask yourself why are the int versions of GCD and LCM members of the Num_Fact class? These functions work on integers only, so there is absolutely no reason to put them in the Num_Fact class. So move them out of the class, it will simplify the answer to your actual question. Second question, why are these functions returning long long int? They have integer arguments and they can never return a value that is bigger than an int. So change them to return int, again this will simplify the answer to your actual question.
With those changes done we can talk about your actual question. As we've seen you already have functions that calculate GCD and LCM on integers, so just use those functions when you want to calculate GCD or LCM on Num_Fact. Like this
Num_Fact GCD(Num_Fact a, Num_Fact b) {
return GCD(a.getnum(), b.getnum());
}
Num_Fact LCM(Num_Fact a, Num_Fact b) {
return LCM(a.getnum(), b.getnum());
}
That's it, really simple. In fact these functions doesn't even need to be friends, since they are only using the public methods of Num_Fact.
My code looks take in user input in the form 'a/b' and does fractional math, then outputting results.The main error I seem to get is no match for 'operator='. Error is given on line 39 and 40. Any help is appreciated.
The errors I get are shown here:
enter image description here
main.cpp
// Add appropriate headers
#include <iostream>
#include <cstdlib>
#include <string>
#include <cmath>
#include <sys/time.h>
#include "rational7.h"
using namespace std;
int main()
{
// ToDo: declare three rational objects using the default constructor
Rational a, b, c;
int length;
char answer='Y';
// Main loop to read in rationals and compute the sum
do {
cout << "Enter the number of fractions to add/multiply: ";
cin >> length;
Rational *fractions = new Rational[length];
for (int i = 0; i < length; i++)
{
fractions[i].set (1,i+1);
fractions[i].output();
}
Rational r_sum, r_product(1);
//tempsum = fractions[0];
//tempproduct = fractions[0];
for (int i = 0; i < length; i++)
{
r_sum = sum(r_sum, fractions[i]); // test r.sum
r_product = product(r_product, fractions[i]); // test
}
//simplify
//cout << "Sum of fractions: " << r_sum.output() << endl;
//cout << "Prod of fractions: " << r_product.output() << endl;
// ToDo: use your input member function to read the first rational
cout << "Enter two rationals to compare ";
a.input();
b.input();
a.output(); // Debug line
b.output(); // Debug line
while (a.getDenominator() == 0 || b.getDenominator() == 0)
{
cout << "wrong input. \n";
cout << "Enter a rational (p/q): \n";
a.input();
b.input();
}
// cout << "Total number of objects created = " << << endl;
cout << "\nTry again (Y/N)?\n";
cin >> answer;
cin.ignore(256,'\n');
} while (answer == 'y' || answer == 'Y');
return 0;
}
rational7.cpp
#include <iostream>
#include <cstdlib>
#include <string>
#include <cmath>
#include <sys/time.h>
#include "rational7.h"
using namespace std;
// ToDO: Implement your class member functions below.
/*
Rational::Rational()
{
numerator = 0;
denominator = 1;
}
Rational::Rational(int num)
{
numerator = num;
denominator = 1;
}
Rational::Rational(int num, int den)
{
Rational r;
numerator = num;
denominator = den;
}
*/
int Rational::counter = 0;
//Three constructors to one
Rational::Rational(int num, int den)
{
numerator = num;
denominator = den;
}
void sum(const Rational &a, const Rational &b)
//void Rational::sum(const Rational &a, const Rational &b)
{
Rational temp;
int num = 0;
int den = 0;
//num = (a.getNumerator()*b.getDenominator() + a.getDenominator()*b.getNumerator());
//den = (a.getDenominator()*b.getDenominator());
num = (a.numerator*b.denominator + a.denominator*b.numerator);
den = (a.denominator*b.denominator);
temp.numerator = num;
temp.denominator = den;
//return temp;
}
//void Rational::product(const Rational &a, const Rational &b)
void product(const Rational &a, const Rational &b)
{
Rational temp;
//int num = (a.getNumerator()*b.getNumerator());
//int den = (a.getDenominator()*b.getDenominator());
int num = (a.numerator*b.numerator);
int den = (a.denominator*b.denominator);
temp.numerator = num;
temp.denominator = den;
//return temp;
}
void Rational::input()
{
string in;
getline(cin, in);
//cin >> in;
// find the index position of /
int indx = in.find("/");
// seperate the numerator
numerator = atoi(in.substr(0, indx).c_str());
// seperate the denominator
denominator = atoi(in.substr(indx+1, in.length()).c_str());
//if(denominator != 0)
Rational(numerator, denominator);
}
void Rational::output()const
{
cout << numerator << "/" << denominator;
}
void Rational::set(int num, int den)
{
numerator = num;
denominator = den;
}
// Two getter functions
int Rational::getNumerator()const
{
return numerator;
}
int Rational::getDenominator()const
{
return denominator;
}
/*
void simplify(int num, int den)
{
gcd(num, den);
}
*/
/*
int gcd (int a, int b)
{
while (a!=0 && b!=0)
{
a = a % b;
if (a!=0)
b = b % a;
}
if (a==0)
return b;
if (b==0)
return a;
}
*/
/*
bool isEqual(const Rational &a, const Rational &b)
{
if (a.numerator * b.denominator == a.denominator * b.numerator)
{
return true;
}
else
{
return false;
}
}
*/
int Rational::getObjectCounter()
{
return counter;
}
rational7.h
#include <iostream>
#include <cstdlib>
#include <string>
#include <cmath>
#include <sys/time.h>
using namespace std;
/* KEEP THIS COMMENT
* class Rational
* represents a Rational number. Remember rational means ratio-nal
* which means there is a numerator and denominator having
* integer values. Using good ADT techniques, we have made member
* variable private (also known as instance variables) and made member
* functions public.
*/
class Rational
{
private:
int numerator;
int denominator;
static int counter;
//void simplify(int num, int den);
public:
/*
// ToDo: Default Constructor
Rational();
// ToDo: Constructor that takes int numerator
Rational(int num);
// ToDo: Constructor that takes int numerator and int denominator
Rational(int num, int den);
*/
// Three constructors to one
Rational(int num = 0, int den = 1);
// ToDo: Member function to read a rational in the form: n/d
void input();
// ToDo: Member function to write a rational as n/d
void output()const;
// ToDo: declare an accessor function to get the numerator
int getNumerator()const;
// ToDo: declare an accessor function to get the denominator
int getDenominator()const;
// object counter 'global'
static int getObjectCounter();
// ToDo: delcare a function called Sum that takes two rational objects
// sets the current object to the sum of the given objects using the
// formula: a/b + c/d = ( a*d + b*c)/(b*sd)
friend void sum(const Rational &a, const Rational &b);
friend void product(const Rational &a, const Rational &b);
void set(int num, int den);
//bool isEqual(const Rational &a, const Rational &b);
};
The compiler informs you that it does't know what operator=() you want to call.
Normally for some types C++ operator= - is it a function that is called to assign values of user defined types. Rational in your case - is a user defined type.
Looking at your code - you declare:
friend void sum(const Rational &a, const Rational &b);
And later call it as r_sum = sum(r_sum, fractions[i]); // test r.sum
Meaning compiler is looking for a function or member function of Rational that can accept void as an argument. operator=(void) - that is because in your case sum returns void.
You can either define such operator yourself.
But I believe what you really want it to return a Rational value from sum:
friend Rational sum(const Rational &a, const Rational &b);
This question already has answers here:
calling destructor explicitly
(2 answers)
Closed 3 years ago.
So I have a class Vector and when I'm calling in main for example the destructor of an object I get an exception. The line of code from the exception file is "free_dbg(block, _UNKNOWN_BLOCK)"; Note that if I do only the reading of the vectors or only the destructor call, I won't get the exception. When I do both together, this is when the problem appears.
Here is the code:
#include "pch.h"
#include <iostream>
#include <fstream>
using namespace std;
class Vector
{
public:
Vector();
~Vector();
Vector(const Vector& vec);
void insert_element(int value, int position);
void delete_element(int position);
void set_nr_elem(int nr) { nr_elem = nr; }
int get_nr_elem() const { return nr_elem; }
int get_element(int position) const { return arr[position]; }
friend istream& operator>>(istream& input, Vector &vec);
friend ostream& operator<<(ostream& output, const Vector &vec);
Vector operator=(const Vector& vec);
void free_memory() { delete[] arr; }
private:
int *arr;
int nr_elem;
};
Vector::Vector()
{
arr = NULL;
nr_elem = 0;
}
Vector::~Vector()
{
delete[]arr;
nr_elem = 0;
}
Vector::Vector(const Vector& vec)
{
arr = new int[vec.nr_elem];
nr_elem = vec.nr_elem;
for (int i = 0; i < nr_elem; i++)
arr[i] = vec.arr[i];
}
void Vector::insert_element(int value, int position)
{
if (position < 0 || position > nr_elem)
{
cout << "Invalid position";
return;
}
arr = (int*)realloc(arr, (nr_elem + 1) * sizeof(int));
for (int i = nr_elem; i >= position + 1; i--)
arr[i] = arr[i - 1];
arr[position] = value;
nr_elem++;
}
void Vector::delete_element(int position)
{
if (position < 0 || position >= nr_elem)
{
cout << "Invalid position";
return;
}
for (int i = position; i < nr_elem; i++)
arr[i] = arr[i + 1];
delete &arr[nr_elem];
nr_elem--;
}
istream& operator>>(istream& input, Vector &vec)
{
int nr;
input >> nr;
for (int i = 0; i < nr; i++)
{
int x;
input >> x;
vec.insert_element(x, vec.get_nr_elem());
}
return input;
}
ostream& operator<<(ostream& output, const Vector &vec)
{
if (vec.get_nr_elem())
{
output << "Number of elements: " << vec.get_nr_elem() << "\n";
output << "The elements: ";
for (int i = 0; i < vec.get_nr_elem(); i++)
output << vec.get_element(i) << " ";
output << "\n";
}
else
{
output << "The vector has no elements";
}
return output;
}
Vector Vector::operator=(const Vector& vec)
{
if (this == &vec)
return *this;
delete[] arr;
arr = new int[vec.nr_elem];
for (int i = 0; i < vec.nr_elem; i++)
arr[i] = vec.arr[i];
nr_elem = vec.nr_elem;
return *this;
}
class Natural_Big_Number
{
public:
void set_sign(char c) { sign = c; }
char get_sign() const { return sign; }
friend istream& operator>>(istream& input, Natural_Big_Number &number);
friend ostream& operator<<(ostream& output, const Natural_Big_Number &number);
friend Natural_Big_Number operator+(const Natural_Big_Number& number1, const Natural_Big_Number& number2);
friend Natural_Big_Number operator-(const Natural_Big_Number& number1, const Natural_Big_Number& number2);
friend Natural_Big_Number& operator*(const Natural_Big_Number& number1, const Natural_Big_Number& number2);
friend Natural_Big_Number& operator/(const Natural_Big_Number& number1, const Natural_Big_Number& number2);
Natural_Big_Number operator=(const Natural_Big_Number& number);
private:
Vector vec;
char sign;
};
istream& operator>>(istream& input, Natural_Big_Number &number)
{
int x;
input >> x;
char c;
input.get();
c = input.get();
if (c == '-')
number.set_sign('-');
else
{
number.set_sign('+');
int digit = (int)c - 48;
number.vec.insert_element(digit, number.vec.get_nr_elem());
}
while ((c = input.get()) >= '0' && c <= '9')
{
int digit = (int)c - 48;
number.vec.insert_element(digit, number.vec.get_nr_elem());
}
return input;
}
ostream& operator<<(ostream& output, const Natural_Big_Number &number)
{
cout << "Number of digits: " << number.vec.get_nr_elem() << '\n';
cout << "The number: ";
if (number.get_sign() == '-')
cout << number.get_sign();
for (int i = 0; i < number.vec.get_nr_elem(); i++)
cout << number.vec.get_element(i);
cout << endl;
return output;
}
Natural_Big_Number operator+(const Natural_Big_Number& number1, const Natural_Big_Number& number2)
{
Natural_Big_Number result;
int carry = 0;
int it_digits1 = number1.vec.get_nr_elem() - 1;
int it_digits2 = number2.vec.get_nr_elem() - 1;
if (number1.get_sign() == number2.get_sign())
{
result.set_sign(number1.get_sign());
while (it_digits1 >= 0 && it_digits2 >= 0)
{
int aux = number1.vec.get_element(it_digits1) + number2.vec.get_element(it_digits2) + carry;
int value = aux % 10;
result.vec.insert_element(value, 0);
carry = aux / 10;
it_digits1--;
it_digits2--;
}
for (int i = 0; i <= it_digits1; i++)
{
int aux = number1.vec.get_element(it_digits1) + carry;
int value = aux % 10;
carry = aux / 10;
result.vec.insert_element(value, 0);
}
for (int i = 0; i <= it_digits2; i++)
{
int aux = number2.vec.get_element(it_digits2) + carry;
int value = aux % 10;
carry = aux / 10;
result.vec.insert_element(value, 0);
}
}
/*else if (number1.get_sign() == '-' && number2.get_sign() == '+')
{
result = number1;
result.set_sign('+');
result = number2 + result;
}*/
cout << result;
return result;
}
Natural_Big_Number operator-(const Natural_Big_Number& number1, const Natural_Big_Number& number2)
{
Natural_Big_Number result;
int carry = 0;
int it_digits1 = number1.vec.get_nr_elem() - 1;
int it_digits2 = number2.vec.get_nr_elem() - 1;
while (it_digits1 >= 0 && it_digits2 >= 0)
{
int aux = number1.vec.get_element(it_digits1) - number2.vec.get_element(it_digits2) + carry;
int value = aux % 10;
result.vec.insert_element(value, 0);
carry = aux / 10;
it_digits1--;
it_digits2--;
}
for (int i = 0; i <= it_digits1; i++)
{
int aux = number1.vec.get_element(it_digits1) + carry;
int value = aux % 10;
carry = aux / 10;
result.vec.insert_element(value, 0);
}
for (int i = 0; i <= it_digits2; i++)
{
int aux = number2.vec.get_element(it_digits2) + carry;
int value = aux % 10;
carry = aux / 10;
result.vec.insert_element(value, 0);
}
cout << result;
return result;
}
Natural_Big_Number Natural_Big_Number::operator=(const Natural_Big_Number& number)
{
if (this == &number)
return *this;
vec.free_memory();
set_sign(number.get_sign());
vec = number.vec;
return *this;
}
int main()
{
ifstream f("date.in");
Natural_Big_Number number1, number2;
f >> number1 >> number2;
number1 = number2;
cout << number1;
return 0;
}
That's because you shouldn't do that.
The destructor is called for you when vec1 goes out of scope.
Your program attempts to destroy vec1 twice, which causes mayhem.
I am trying to create a fraction class that can do operations on fractions just like the way we did it by hand in elementary school. It works fine with positive numbers but I have tried implementing it with negative numbers and I get breakpoint error. It would be great if someone can tell me what is wrong with it.
#include <iostream>
#include <cmath>
using namespace std;
class fraction
{
private:
long int n;
long int d;
long int gcd();
public:
fraction(long int, long int);
long int num(); //returns num
long int denom(); //returns denom
void print(); //print fraction
void reduce(); //reduce fraction to lowest terms
friend double convert(fraction); //convert function to double
friend fraction operator+ (fraction, fraction);//add two fractions, answer in reduced form
friend fraction operator- (fraction, fraction);//subtract two fractions, reduced
};
long int fraction::gcd()
{
long int divisor = 0;
for (long int i = 1; (i <= n && i <= d) ; i++)
{
if ((n % i == 0) && (d % i == 0))
{
divisor=i;
}
}
return divisor;
}
fraction::fraction(long int x, long int y) //constructor
{
n=x;
d=y;
if ((x <= 0) && (y <= 0))
{
n = -x;
d = -y;
}
}
void fraction::reduce() //change value of n and d
{
long int num = n/gcd();
long int denom = d/gcd();
n = num;
d = denom;
}
long int fraction::num()
{
return n;
}
long int fraction::denom()
{
return d;
}
void fraction::print()
{
cout << n << "/" << d;
}
fraction operator- (fraction x, fraction y)
{
x.reduce();
y.reduce();
fraction temp;
temp.n = (x.n)*(y.d) - y.n*(x.d);
temp.d = (x.d)*(y.d);
temp.reduce();
return temp;
}
int main()
{
fraction f(-5,100), g(-1,-2);
(f-g).print; //returns error!
return 0;
}
The error is caused by the fact that print() is a non-const member function.
When you use:
(f-g).print();
The function is called an a temporary object, which is good for calling const member functions, not non-const member functions.
You can resolve this problem by:
Changing print() to a const member function.
By assigning f-g to an object and calling print on that object.
fraction res = f-g;
res.print();
I would recommend using the first method.
Update
You have a problem in gcd when either n or d is negative. Change it to:
long int fraction::gcd()
{
long int divisor = 1;
// Deal with only positive numbers when computing the gcd.
long int tempN = n < 0 ? -n : n;
long int tempD = d < 0 ? -d : d;
for (long int i = 1; (i <= tempN && i <= tempD) ; i++)
{
if ((tempN % i == 0) && (tempD % i == 0))
{
divisor=i;
}
}
return divisor;
}
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
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. (operator<< and operator>> 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:
#ifndef _POLYNOMIAL_H
#define _POLYNOMIAL_H
#include <iostream>
#include <vector>
#include <sstream>
using namespace std;
class Polynomial {
public:
Polynomial();
Polynomial(vector<double> iCoefficients, vector<int> iExponents);
int Degree() const;
double Evaluate(double x) const;
Polynomial Derivative() const;
friend Polynomial operator+(const Polynomial & p, const Polynomial & p2);
friend Polynomial operator*(const Polynomial & p, const Polynomial & p2);
friend ostream& operator<<(ostream& out, const Polynomial & p);
friend istream& operator>>(istream& in, Polynomial & p);
private:
vector<double> coefficients;
};
#endif
#include "polynomial.h"
#include <stdexcept>
#include <vector>
#include <cmath>
using namespace std;
// Default Constructor
Polynomial::Polynomial() {
coefficients.push_back(0);
}
// Constructor for a Polynomial
Polynomial::Polynomial(vector<double> iCoefficients, vector<int> iExponents) {
for (int i = 0; i < iExponents[0]; i++) {
coefficients.push_back(0);
}
for (size_t i = 0; i < 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 <= 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 <= Degree(); i++) {
// result.coefficients[i] = coefficients[i] * (Degree() - i);
// }
// return result;
}
// Returns polynomial object that is the sum of parameters
Polynomial operator+(const Polynomial & p, const Polynomial & p2) {
int d = p.Degree();
int d2 = p2.Degree();
Polynomial sum;
for (int j = 0; j < d; j++) {
for (int i = 0; i < 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 & p, const Polynomial & p2) {
int d = p.Degree();
int d2 = p2.Degree();
Polynomial product;
for (int j = 0; j < d; j++) {
for (int i = 0; i < d2; i ++) {
product.coefficients.push_back(p.coefficients[j] * p2.coefficients[i]);
}
}
return product;
}
// Output operator
ostream& operator<<(ostream& out, const Polynomial & p) {
for (int i = 0; i <= p.Degree(); i++) {
if(i == 0 && p.Degree() <= 1) {
out << 0;
}
if (p.coefficients[i] != 0 && i != 0) {
out << '+';
}
if (p.coefficients[i] != 0) {
out << p.coefficients[i];
if(i < (p.Degree() - 1)) {
out << "x^";
out << (i - p.Degree()) * (-1);
}
}
}
return out;
}
// Input operator
istream& operator>>(istream& in, Polynomial & p) {
char ch;
int exponent;
double coefficient;
vector<double> coefficients;
vector<int> exponents;
while(isspace(ch) == false) {
ch = in.peek();
if(ch == '+') {
in.ignore();
in >> coefficient;
}
else if(ch == '-') {
in.ignore();
in >> coefficient;
coefficient = coefficient * (-1);
}
else {
in >> coefficient;
}
ch = in.peek();
if((ch <= 'z') && (ch >= 'a')) {
in >> ch;
ch = in.peek();
if(ch == '^') {
in.ignore();
in >> exponent;
}
else
exponent = 1;
}
else
exponent = 0;
coefficients.push_back(coefficient);
exponents.push_back(exponent);
}
p = Polynomial(coefficients, exponents);
return in;
}
#include <iostream>
#include <sstream>
#include <string>
#include <cmath>
#include "polynomial.h"
using namespace std;
bool testPolynomial(const Polynomial& p, string expected);
bool testOperations(const Polynomial& p, int degree, double expected);
bool testInput(string s);
int main() {
int errors = 0;
cerr << "Note: Nearly all of the tests expect a working output operator. If a test fails, check that first" << endl;
cerr << "Testing default constructor" << endl;
Polynomial p1; // test default constructor
errors += testPolynomial(p1, "0");
cerr << "Testing explicit value constructor" << endl;
double c_arr[] = {1.1, 2, 4, 7};
int e_arr[] = {6, 3, 2, 0};
vector<double> c(c_arr, c_arr+4);
vector<int> 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 << '1' << endl;
Polynomial p3(c, e);
errors += testPolynomial(p3, "0");
cout << '2' << endl;
cerr << "Testing operations" << endl;
double c2_arr[] = {-1.1, 2, -4, 7};
int e2_arr[] = {4, 3, 2, 0};
vector<double> c2(c2_arr, c2_arr+4);
vector<int> 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<double> c3 = vector<double>(c_arr3, c_arr3+1);
vector<int> e3 = vector<int>(e_arr3, e_arr3+1);
Polynomial p5(c3, e3);
errors += testPolynomial(p2 * p5 + p2, "0");
errors += testPolynomial(p5, "-1");
cerr << "Testing input operator." << 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& p, string expected) {
ostringstream out;
out << p;
if (out.str() != expected) {
cerr << "Test failed: expected " << expected << " got " << out.str() << endl;
return true;
} else {
return false;
}
}
bool testOperations(const Polynomial& p, int degree, double expected) {
if(p.Degree() != degree) {
cerr << "Failed Degree operation" << endl;
return true;
}
double result = p.Evaluate(2.0);
if (fabs(result - expected) > 1e-5) {
cerr << "Failed Evaluation operation" << endl;
}
return false;
}
bool testInput(string s) {
Polynomial p;
istringstream in(s+" ");
in >> p;
ostringstream out;
out << p;
if (out.str() != s) {
cerr << "Failed input test. Expected: " << s << " got " << out.str() << endl;
return true;
}
return false;
}
The Polynomial::Degree() function has an off-by-one bug; it should return size()-1
In order to convert the lists of coefficients and exponents, first find the maximal exponent; this will be the degree of the polynomial:
int degree = *std::max_element(iExponents.begin(), iExponents.end());
Then, initialize coefficients with this number of zeros (plus one, see above):
coefficients.assign(degree + 1, 0);
Then, set each coefficient, just like you did.
However, it is much better to use ascending order of powers/exponents! This way, you don't need to calculate Degree()-i all the time, you can use i instead.
for (size_t i = 0; i < iExponents.size(); i++) {
coefficients[iExponents[i]] += iCoefficients[i];
}
Note += in the code above; it handles polynomials like 3x+4x+5x, making that equivalent to 12x.
Your addition and multiplication algorithms are completely wrong. You should first set the degree of the output polynomial, just like you did in the constructor:
Polynomial operator+(const Polynomial & p, const Polynomial & p2)
{
int d = p.Degree();
int d2 = p2.Degree();
Polynomial sum;
sum.coefficients.assign(std::max(d, d2) + 1, 0);
...
}
The rest should be easier, once you try to think about it.
After performing the addition, you might want to check for zero highest-degree coefficients; for example, when you add 2x^2+x+1 and -2x^2+x+1, you get 0x^2+2x+2, which you might want to convert to 2x+2:
while (coefficients.back() == 0)
coefficients.resize(coefficients.size() - 1);
if (coefficients.empty())
coefficients.push_back(0);
Derivative should be easy, once you get operator+ and operator* right.