exc_arithmetic error, c++ xcode 4.62 - c++

I'm a beginner of c++. I want know why the exception is thrown at this line:
operator double() const
{
return this->denominator/this->numerator;
}
I found numerator == 0,but I have given default values in the ctor. Why? Please help me.
class Rational {
public:
int numerator;
int denominator;
Rational(int numerator = 2, int denominator = 1)
{
numerator = 2;
denominator = 1;
};
operator double() const
{
return this->denominator/this->numerator;
};
};
int main(int argc, const char * argv[])
{
Rational r(1, 2);
cout << r;
// double d = 0.5*r;
return 0;
}

First, this line is very wrong:
Rational(int numerator = 2, int denominator = 1){ numerator = 2; denominator = 1;};
The arguments numerator and denominator are in the stack frame of your ctor thus hiding your class's members Rational::numerator and Rational::denominator and secondly, you are completely ignoring what the caller actually sends as its arguments (not because you specify the default values, but because you explicitly set numerator=2; denominator=1. This line should actually be:
Rational(int numerator = 2, int denominator = 1){ this->numerator = numerator; this->denominator = denominator;};
OR you could use an initializer list (and overloaded constructors):
Rational() : numerator(2), denominator(1) {};
Rational(int numerator, int denominator) : numerator(numerator), denominator(denominator) {};
Now, the second problem is that int/int => int :: dividing an integer by another integer yields integer division, you need to cast one of your int's to double so that both int's are upconverted to double before calculating the division, like so:
operator double() const{ return ((double)this->denominator)/this->numerator;};

Rational(int numerator = 2, int denominator = 1)
{
numerator = 2;
denominator = 1;
};
I would change this to
Rational(int numerator, int denominator)
{
this->numerator = numerator;
this->denominator = denominator;
};
I don't know exactly if this is causing your problem, but I think it's contributing to it. Your call to Rational(int,int) will still work fine and add your specified values into the Object you're creating.
The issue with your code, is scope. I believe you were just re-assigning the arguments/parameters instead of actually re-assigning your instance variables, which I'm assuming was your goal.

Related

how to overload minus operator to subtract two fractional numbers?

I want to subtract two fractional numbers using operator overloading. I have write a piece of code in order to accomplish this task:
#include<iostream>
using namespace std;
void HCF(int& a, int& b)
{
int m, n;
m = a;
n = b;
while (m != n)
{
if (m > n)
m = m - n;
else
n = n - m;
}
a = a / m;
b = b / m;
}
class Rational {
int x1;
int y1;
public:
void simplify()
{
int m, n, r;
n = fabs(y1);
m = fabs(x1);
while (r = m % n)//Find the Maximum Common Number of m,n
{
m = n;
n = r;
}
y1 /= n; // Simplification
x1 /= n;
if (y1 < 0) // Convert denominator to positive number
{
y1 = -y1;
x1 = -x1;
}
}
Rational(int num = 0, int denom = 1)
{
if (denom) {
x1 = num;
y1 = denom;
}
else {
x1 = 0;
y1 = 1;
}
}
Rational(const Rational& copy)//Copy Constructor
{
x1 = copy.x1;
y1 = copy.y1;
}
Rational operator-(const Rational& x) const //Overloaded minus operator
{
Rational temp;
temp.x1 = x1 * x.y1 - x.x1 * y1;
temp.y1 = y1 * x.y1;
temp.simplify();
return temp;
}
operator string() const //Overloaded string operator
{
int numerator = x1, denominator = y1;
HCF(numerator, denominator);
string str;
if (denominator == 1)
str = to_string(numerator);
else
str = to_string(numerator) + "/" + to_string(denominator);
return str;
}
};
int main()
{
Rational a(5, 1);
Rational b(3, 4);
Rational c;
Rational d;
Rational x(5, 1);
c = a - x;
string expected1 = "0"; //Expected value
string actual1 = (string)c;//Actual value
cout << actual1.compare(expected1);//Comparing actual and expected value
d = c - b;
string expected2 = "-3/4";
string actual2 = (string)d;
cout << actual2.compare(expected2);
}
As we can see, in the main() function, both cout statements should print 0 because when we compare both strings, they must be equal. But the problem is, when I run this program, it prints nothing, and I don't know why.
My operator string() converts an integer fraction into a string. My operator- takes the LCM and finds the final value after subtracting two fractional numbers. In the main() function, I have declared five objects for class Rational, and then I simply perform subtraction and then I compare the expected and actual values, which should return 0 in the cout statement.
I have also used the simplify() member function to check whether the fraction is completely in simpler form or not. For example, it should simplify 2/4 into 1/2.
Where is the mistake? All other functions except operator- are running correctly. The real problem is with the operator-, ie when we perform c=a-x, the value of c would be 0 as a string. Similarly, if we perform d=c-b then the expected value should be -3/4 as a string.
I have also tried to run this code on Google Test, but it fails the test case.
Use this GCD (greatest common divisor) function to implement your HCF function. Yours currently exhibits an endless loop when given 0 as a first argument.
To reduce a fraction, divide numerator and denominator by their greatest common divisor.
This is called the Euclidean algorithm.
template <typename T>
T GCD(T a, T b) {
while (b != 0)
{
T t = a % b;
a = b;
b = t;
}
return std::max(a, -a);
}

How do I create a fraction class with two friend functions in c++

I have an assignment that requires alot of use with classes, the idea of the code is to manipulate fractions to find greatest common denominator (GCD) and other things.
What I need (I know this is long):
Create a Fraction class with 2 private member variables numerator and denominator....one constructor with 2 integer parameters num and den with default values 0 and 1......one display function that prints out a fraction in the format numerator/denominator in the proper form such as 2/3 or 1/2. (2/4 for example should be displayed as 1/2)
HINTS FROM PROFESSOR:
Add a public membeer function called void proper().... that sets numerator and denomonator to the proper form by dividing both by the GCD(greatest common denominator) of them (example... you declare 12/18... after calling proper()...it becomes 2/3 (as the GCD of these is 6)
use public member function GCD() to get the greatest common denominator of the numerator and demoniator...(example 2/4... GCD() returns 2....for 12/18...GCD() returns 6).
[b]Code provided for GCD()
int GCD()
{
int gcd = 0;
int r=0;
u = numerator;
v = denominator;
while (true) {
if (v==0){
gcd = u;
break;
}
else {
r = u%v;
u =v;
v=r;
}
}
return gcd;
}
THEN
Create 2 functions as FRIEND functions of class fraction.
The first one called "sum" takes 2 fraction objects as parameters, it returns a fraction object with the result of the sum of the 2 fraction objects.(example... suppose a=1/4...b=1/2... the result of sum(a,b) should be 3/4.
The second one called "compare"...takes 2 fraction objects as parameters.... it returns 1 if the 2 are equal... and 0 if not. (example....a=1/2...b=2/4.. the result of compare(a,b) is 1)
Write main function to declare fraction objects and demonstrate a working code.
[/b]
So thats what im looking at... here is what I have so far... I know its not very much...
#include <iostream>
using namespace std;
class fraction
{
void friend sum();
void friend compare ();
private:
int numerator;
int denominator;
public:
fraction(int num = 0, int den = 1);
int GCD();
void proper();
void fraction::proper()
{
}
int GCD()
{
int gcd = 0;
int r=0;
u = numerator;
v = denominator;
while (true) {
if (v==0){
gcd = u;
}
else {
r = u%v;
u =v;
}
}
return gcd;
}
void sum()
{
}
void compare()
{
}
void main()
{
}
I am VERY confused about how to set this up with a "1/2" type input... im use to simple inputs like 1 or 2. If someone could help fill in the gaps a bit I would appreciate it... (keep in mind Im a beginner..)... this is my first time working with anything like this and I am in way over my head
Thank you!

How to implement greatest common divisor to simplify fractions

#include <iostream>
using namespace std;
int g_c_d(int n, int d);
class Fraction
{
private:
//variables to store numerator and denominator
int num;
int denom;
public:
Fraction(){}
Fraction(int num): num(num) {}
Fraction(int num, int denom): num(num), denom(denom) {}
void set_num(int n){ num = n;}
void set_denom(int d){ denom = d;}
int get_numerator() const {return num;}
int get_denominator() const {return denom;}
};
int g_c_d(int n, int d){
return d == 0? n : g_c_d(d, n % d);
}
istream &operator>> (istream &input, Fraction &f)
{
int n, d;
char slash;
input >> n;
input >> slash;
input >> d;
if (d == 0) {n = 0;} //if denom is 0; fraction = 0/0
f = Fraction(n, d);
return input;
}
ostream &operator<<(ostream &output, const Fraction &frac)
{
return output << frac.get_numerator() << "/" << frac.get_denominator();
}
int main()
{
int n, d;
Fraction frac;
int gcd;
n = frac.get_numerator();
d = frac.get_denominator();
gcd = g_c_d(frac.get_numerator() , frac.get_denominator());
cout << "Enter a fraction" << endl;
cin >> frac;
frac.set_num(n/gcd);
frac.set_denom(d/gcd);
cout << "your fraction is: ";
cout << frac << endl;
return 0;
}
Hi im trying to simplify fractions entered by a user. However everytime I enter a fraction that is to be simplified the output returned is "1/0".
Can some one please help, it'll be massively appreciated!
The problem is that you do all your computations on frac before asking the user to input a fraction — and then you overwrite whatever the user inputs. You need to move this bit:
cout << "Enter a fraction" << endl;
cin >> frac;
much, much higher up.
When you are setting up the code you have:
Fraction frac;
This calls the default constructor for Fraction. Because you never initialized the members in the constructor you get the default initizliation for the int type which is 0. Then:
n = frac.get_numerator();
d = frac.get_denominator();
This makes n and d 0. From that point onwards you are using those values of n and d. These values however are not the values from the user inputted frac but are just the values you get from the defaults. Change your code to read in the user inputted value for frac before you do any calculations.
The main lesson to learn here is to make sure you don't use uninitialized variables. Generally speaking when you compile with all warnings enabled this is the sort of thing that compilers will warn about.
You may be diving by zero because the default constructor doesn't assign value to the denominator. In the case where the denominator is set to zero, the gcd() function will divide by zero, on the first time in main.

Overloading operator + for fractions (using lcm)

I want to compute the sum of two fraction using lcm of numerator and denominator. That means as a result I want to get a fraction in the reduced form. I have the following cpp file.
#include <iostream> //need it for cin and cout
#include "fraction.h"
Fraction::Fraction()
{
num = 1;
den = 1;
}
Fraction::Fraction(int n, int d)
{
int tmp_gcd = gcd(n, d);
num = n / tmp_gcd;
den = d / tmp_gcd;
}
int Fraction::gcd(int a, int b)
{
int tmp_gcd = 1;
// Implement GCD of two numbers;
return tmp_gcd;
}
int Fraction::lcm(int a, int b)
{
return a * b / gcd(a, b);
}
Fraction operator+(const Fraction&a,const Fraction &b)
{
int c=(lcm(b.den,a.den)/b.den)*a.num+b.num*(lcm(b.den,a.den)/a.den);
int d=lcm(b.den,a.den);
Fraction result(c,d);
return result;
}
However this code does not work because lcm is not defined in this scope.
What is the key that allows lcm work in this scope? If you please could explain more, I would be very thankful.
lcm is a member of Fraction. You can refer to it just as lcm within members of Fraction; but operator+ isn't a member, so you'll have to use the qualified name Fraction::lcm.
It will also need to be static. (Hopefully it already is, but I can't see the declaration to be sure).

extending operator overload in C++

I am fairly new in C++ (I have spent all my life in C so I thought it's time to invest some time in learning a new language in order to enrich my knowledge :) ). I have a class named "Rational", I have all its specific functions for getters, setters, constructors, etc.(it's not relevant here). The interesting part is when I try to overload the +,-,,/ operators. I am able to successfully do this between two Rational objects, for example Rational a(1,5),b(5,5),c; c = a + b; so all this works just fine. Now I am trying to upgrade my class by trying to +,-,,/ between a Rational and an integer, for example 2 + a, 10 - b etc. Here is (a snippet of)my code for overloading between Rationals:
Rational.cc
...
Rational Rational::operator+(Rational B) {
int Num;
int Den;
Num = p * B.q + q * B.p;
Den = q * B.q;
Rational C(Num, Den);
C.simplifierFraction();
return C;
}
Rational Rational::operator-(Rational B) {
int Num;
int Den;
Num = p * B.q - q * B.p;
Den = q * B.q;
Rational C(Num, Den);
C.simplifierFraction();
return C;
}
Rational Rational::operator*(Rational B)
{
int Num;
int Den;
Num = p * B.p;
Den = q * B.q;
Rational C(Num, Den);
C.simplifierFraction();
return C;
}
Rational Rational::operator/(Rational B)
{
int Num;
int Den;
Rational invB = inverse(B);
Num = p * invB.p;
Den = q * invB.q;
Rational C(Num, Den);
C.simplifierFraction();
return C;
}
...
Rational.h
Rational operator+(Rational B);
Rational operator-(Rational B);
Rational operator*(Rational B);
Rational operator/(Rational B);
private:
int p;
int q;
protected:
TestRat.cc
int main() {
...
const Rational demi(1,2);
const Rational tiers(1,3);
const Rational quart(1,4);
r0 = demi + tiers - quart;
r1 = 1 + demi;
r2 = 2 - tiers;
r3 = 3 * quart;
r4 = 1 / r0;
...
So when I try to run TestRat.cc it says:
testrat.cc:31: error: no match for ‘operator+’ in ‘1 + r9’
testrat.cc:52: error: passing ‘const Rational’ as ‘this’ argument of ‘Rational Rational::operator+(Rational)’ discards qualifiers
testrat.cc:53: error: no match for ‘operator+’ in ‘1 + demi’
testrat.cc:54: error: no match for ‘operator-’ in ‘2 - tiers’
testrat.cc:55: error: no match for ‘operator*’ in ‘3 * quart’
testrat.cc:56: error: no match for ‘operator/’ in ‘1 / r0’
What must I do in order to be able to make this work?
Thanks!
tl;dr:
your operators should be declared as:
Rational operator+(const Rational& B) const;
well... these ones, at least. operator = should return a reference to *this, but that's outside the scope of this questions. Also, those operators are defined to work on Rational objects, whereas
r1 = 1 + demi;
attempts to operate on an int and a Rational object. You'll have to define outside the class an appropriate operator:
inline Rational operator+(int, const Rational& r)
{
//...
}
I suggest you start learning C++ with a good book though. Just picking up stuff from here and there isn't really going to work.