How to implement greatest common divisor to simplify fractions - c++

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

Related

C++ Fraction Calculator using Classes and Functions

I am new to StackOverflow, and starting at a new school. I was hoping for some guidance on an assignment. The assignment is to calculate an expression involving two fractions, and output the result. I've been working on this program for days with the knowledge from my textbook, but I guess I am still confused on how to implement functions within a class. I know what I want to do with my values, but I am confused on where to assign them. I tried to read in my values, but when outputting, I get garbage. Any help would be greatly appreciated.
#include <iostream>
using namespace std;
class fraction // Fraction class definition
{
int num,
den;
public:
fraction() // default constructor
{
num = 0;
den = 1;
}
void add(fraction f1, fraction f2) // addition fcn
{
num = (f1.num*f2.den) + (f2.num*f1.den);
den = f1.den*f2.den;
}
void subtract(fraction f1, fraction f2) // subtraction fcn
{
num = (f1.num*f2.den) - (f2.num*f1.den);
den = f1.den*f2.den;
}
void multiply(fraction f1, fraction f2) // multiplying fcn
{
num = f1.num*f2.num;
den = f1.den*f2.den;
}
void divide(fraction f1, fraction f2) // dividing fcn
{
num = f1.num*f2.den;
den = f1.den*f2.num;
}
void output()
{
cout << num << "/" << den << endl;
}
}; // end Fraction class
int main()
{ // begin main
fraction result;
fraction n;
fraction d;
int n1, n2, d1, d2 = 0;
char op;
cout << "Please enter an expression containing two fractions:" << endl;
cin >> n1 >> d1 >> op >> n2 >> d2;
switch (op)
{ // begin switch
case '+':
result.add(n, d);
result.output();
break;
case '-':
result.subtract(n, d);
result.output();
break;
case '*':
result.multiply(n, d);
result.output();
break;
case'/':
result.divide(n, d);
result.output();
break;
} // end switch
//fraction f1(n1, d1);
//fraction f2(n2, d2);
} // end main
The actual answer was given in the very first comment of John3136. Hence, I struggled a bit but finally realized that you probably didn't recognize. So, I will elaborate this a bit:
In main(), you do this:
int n1, n2, d1, d2 = 0;
char op;
cout << "Please enter an expression containing two fractions:" << endl;
cin >> n1 >> d1 >> op >> n2 >> d2;
Stepping through with a debugger, you will realize that this part of program works as expected. After input of e.g.
1 2 + 3 4
the variables will show the following values:
n1: 1
d1: 2
n2: 3
d2: 4
op: '+'
Live demo on ideone
Stepping further, the program pointer will move to
result.add(n, d);
Hmm. You want to add n and d but the debugger says:
n: { num: 0, den: 1 }
d: { num: 0, den: 1 }
The values of n.num, n.den, d.num, and d.den are there as you provided a default constructor for class fraction which effects precisely this.
So, how do you think will n1 be moved to n.num, d1 to n.den, and so on?
What's really missing is a constructor for class fraction to load members num and den (in this case of n and d) with the specified values.
You could introduce a second constructor. In this case, you can modify (and extend) your existing, also:
class fraction {
private:
int num, den; // numerator, denominator
public:
explicit fraction(int num = 0, int den = 1): num(num), den(den) { }
};
Looks confusing? I will explain:
I gave the constructor arguments, but the arguments got default values.
Hence, it still can be used as default constructor. Doing fraction a; will construct fraction 0/1 as before. But, now, you can also do fraction b(3, 2); to construct fraction 3/2. You can even do fraction d(3);. This will construct fraction 3/1 which sounds reasonable to me.
I named the arguments equal to the members. Looks funny and, may be, a bit confusing but it seems to be very usual nowadays. (Actually, I learned this in SO a short time ago.) However, the compiler will understand this correctly (even if it is the one of MS).
I prefixed the constructor with explicit. This prevents that the constructor might be used for implicit conversion. Without explicit, the following would work as well: fraction c; c = 1; i.e. assignment of class fraction from an int. This is a question of design whether or not you want to support this. Implicit conversion can be quite convenient but the compiler might apply it where you don't expect it. I personally got used to make nearly every constructor explicit as I don't like to "lose control" of what the compiler is doing.
Modifying the above constructor as recommended you then can use your class, e.g.:
fraction a(3, 2), b(1, 2);
fraction result; result.add(a, b);
result.output();
Now, it should print the sum of fractions a and b.
A last note:
I consider O'Neil's hint with the operator overloading basically reasonable. You will find answers with code samples in SO. (Some of them, written by me.) ;-) On the other hand, operator overloading is just another handicap. I wouldn't bother too much about this. (May be, in a second version...)
Finally, I made an MCVE to demonstrate the above mentioned with sample code:
#include <iostream>
using namespace std;
class fraction {
private:
int num, den; // numerator, denominator
public:
explicit fraction(int num = 0, int den = 1): num(num), den(den) { }
void add(fraction f1, fraction f2) // addition fcn
{
num = (f1.num * f2.den) + (f2.num * f1.den);
den = f1.den * f2.den;
}
void output() { cout << num << "/" << den << endl; }
};
int main()
{
fraction a0;
cout << "fraction a0: "; a0.output();
fraction a(3, 2), b(1);
cout << "fraction a(3, 2): "; a.output();
cout << "fraction b(1): "; b.output();
fraction c; c.add(a, b);
cout << "fraction c = a + b: "; c.output();
// assignment (using default assignment operator)
fraction d; d = c;
cout << "faction d = c; d: "; d.output();
#if 0 // disabled code
// This will work only if constructor is not explicit:
fraction e = 1; e = 1;
cout << "fraction e; e = 1; e: "; e.output();
#endif // 0
// fraction from input
int n1, n2;
cout << "Input n1 n2: "; cin >> n1 >> n2;
fraction in(n1, n2);
cout << "fraction in(n1, n2): "; in.output();
// done
return 0;
}
Input:
123 321
Output:
fraction a0: 0/1
fraction a(3, 2): 3/2
fraction b(1): 1/1
fraction c = a + b: 5/2
faction d = c; d: 5/2
Input n1 n2: fraction in(n1, n2): 123/321
Live demo on ideone.
After having read your comment, I'm in doubt whether you already understood the concept of class and member function. I'll try my best:
Are you aware that your function add() is a member function? It is as you defined the function inside your class fraction. That means, add() cannot be called without an object (i.e. an instance of fraction).
If you write this into your main() function you get a compiler error:
fraction a, b;
fraction::add(a, b);
Live demo on ideone
The object is another argument that a call of a (non-static) member function (like fraction::add()) urgently needs. May be, you didn't recognize the thing in front of the dot as function argument but it is.
fraction c; c.add(a, b);
/* ^ ^ ^
* | | +--- 2nd argument
* | +------ 1st argument
* +------------ object (which becomes THE this POINTER inside fraction::add())
*/
Hence, fraction.add() has actually three arguments. So, how may the object be accessed? For this, C++ provides a special keyword this. this is a pointer to class, and it provides a pointer to the object for which the member function has been called. Using this, you can access all (other) members of this class – member variables as well as member functions.
(Decades ago, when I tried to understand by myself how C++ and OOP are working, I had a look into the compiled assembly code. I was really surprised to realize that the object before the dot was exactly handled like the other arguments in the parentheses. This was one of my personal Heureka!-moments.)
Access to members (of the same class) can be done inside a member function with this-> but it can be left out as well as the compiler will add this silently if applicable.
Your member function fraction::add() is actually a demonstration of this.
It gets two arguments f1 and f2, processes their members (f1.num, f1.den, f2.num, and f2.den) to perform the addition of fractions, and stores the resp. results in member variables num and den. In this case, num is the same as this->num and den the same as this->den. So, where is this pointing to? This depends on the object for which the member function has been called. For e.g.:
result.add(n, d);
inside of fraction::add(), this will point to result.

Unexpected addition operator with my class

I apologize if the question is Naive.
I am trying to overload the addition operator for fractions. My intent was to add fractions but for some reason it is adding the integers. Can some one explain why is it performing the integer addition. Code is below.
#include <iostream>
#include <string>
using namespace std;
class Fraction{
long numerator;
long denominator;
long gcd(long num1, long num2);
long lcm(long num1, long num2);
public:
void convert_int_to_fraction(int num);
void reduce();
Fraction(int num);
Fraction(){
numerator = 0;
denominator = 0;
}
Fraction(long num, long den);
Fraction operator+(Fraction fraction);
friend ostream& operator<<(ostream& os, const Fraction& fracNumber);
};
void Fraction::convert_int_to_fraction(int num){
denominator = 1;
numerator = long(num);
reduce();
}
Fraction::Fraction(int num){
convert_int_to_fraction(num);
}
long Fraction::gcd(long num1, long num2){
if(num1 == 0)
return num2;
else
return (gcd(num2 % num1, num1));
}
//Math function to calculate LCM
long Fraction::lcm(long num1, long num2){
long great_Divisor = gcd(num1, num2);
return ((num1/great_Divisor) * num2);
}
//Reduce fraction to its minimal
void Fraction::reduce(){
if(denominator!=0){
long great_Divisor = gcd(numerator, denominator);
numerator /= great_Divisor;
denominator /= great_Divisor;
if(denominator < 0 && numerator > 0){
denominator = -denominator;
numerator = -numerator;
}
}
}
Fraction::Fraction(long num, long den):numerator(num), denominator(den){
reduce();
}
ostream& operator<<(ostream& os, const Fraction& fracNumber){
os << fracNumber.numerator << "/" << fracNumber.denominator ;
return os;
}
Fraction Fraction::operator+(Fraction fraction){
Fraction result;
long least_Multiple = lcm(denominator, fraction.denominator);
result.denominator = (least_Multiple);
long result_Numerator = ((numerator * (least_Multiple/denominator)) +
(fraction.numerator * (least_Multiple/fraction.denominator)));
result.numerator = (result_Numerator);
result.reduce();
return result;
}
int main(){
Fraction frac1(2,4);
cout << frac1 + 2 << endl;
return 0;
}
The output is 5/2 So I tried to do it the other way round
cout << 2 + frac1 << endl;
This is giving me error. So now I tried to fix this by implementing these two functions.
Fraction::operator int(){
return convert_fraction_to_int();
}
int Fraction::convert_fraction_to_int(){
return ((int)(numerator/denominator));
}
Now even the first operation cout doesnt work. But the best thing is everything works fine when I typecast the variables. Can anyone explain why it is working in the first case, why not in the second case and why broken in the third case.
.My intent was to add fractions but for some reason it is adding the integers. Can some one explain why is it performing the integer addition.
There is a converting constructor from int to Fraction.
frac1 + 2 is being converted to frac1 + Fraction(2) by the compiler.
Update
If you want the compiler to be able support both frac1 + 2 and 2 + frac1, you can make the operator+ function a non-member function.
friend Fraction operator+(Fraction const& lhs, Fraction const& rhs);
and implement it as:
Fraction operator+(Fraction const& lhs, Fraction const& rhs)
{
Fraction result;
// Needed to make lcm and gcd static member functions since
// they work independent of the member variables.
long least_Multiple = Fraction::lcm(lhs.denominator, rhs.denominator);
result.denominator = (least_Multiple);
long result_Numerator = ((lhs.numerator * (least_Multiple/lhs.denominator)) +
(rhs.numerator * (least_Multiple/rhs.denominator)));
result.numerator = (result_Numerator);
result.reduce();
return result;
}
Now, you can use
Fraction frac1(2,4);
Fraction frac2(3,7);
cout << frac1 + 2 << endl;
cout << 3 + frac1 << endl;
cout << frac1 + frac2 << endl;

Print float as decimal and fix wrong output

I was experimenting with classes and I wrote this example code. The user enters their register number and two marks. The output should be their register number and the average of the two input marks. I have two questions:
How do I use the float type to display the output average marks in decimal form if I am using constructors?
Why is the output of the register number not correct? The code is given below.
#include<iostream.h>
#include<conio.h>
class abc
{
int reg, mark1, mark2;
public:
int avg;
abc(int reg, int mark1, int mark2)
{
avg = (mark1 + mark2) / 2;
}
void display()
{
cout<<"Your average mark is:\n"<<avg<<"\n";
cout<<"Your Register Number is:\n"<<reg<<"\n";
}
};
void main()
{
clrscr();
int num, m1, m2;
cout << "Enter your register number\n";
cin >> num;
cout << "Enter your Mark 1 and Mark 2:\n";
cin >> m1 >> m2;
abc s1(num,m1,m2);
s1.display();
getch();
}
I am getting the average (without the decimal) and the register number output is 11196.
In C++ the constructor arguments are not automatically stored in the class members. I would change your class declaration to the following, note that I have used different names for the members and function arguments (I like to use m_ for private member variables).
class abc
{
int m_reg, m_mark1, m_mark2;
public:
int avg;
abc (int reg, int mark1, int mark2)
: m_reg(reg), m_mark1(mark1), m_mark2(mark2)
{
avg = (m_mark1+m_mark2)/2;
}
void display()
{
cout<<"Your average mark is:\n"<<avg<<"\n";
cout<<"Your Register Number is:\n"<<m_reg<<"\n";
}
};
If you expect your result to be a decimal (and not rounded or floored to the nearest integer) you need to change your average declaration and calculation to:
// The new declaration
double avg;
// In your constructor
avg = (double) (m_mark1 + m_mark2) / 2.0;
All you need to do is add value to reg property in your class constructor:
abc (int r, int mark1, int mark2)
{
reg = r;
avg = (mark1+mark2)/2;
}
In addition to that, why is avg an integer instead of double? Consider this:
class abc
{
int reg,mark1,mark2;
public:
double avg;
abc (int r, int mark1, int mark2)
{
reg = r;
avg = (double)(mark1+mark2)/2.00;
}
void display()
{
cout<<"Your average mark is:\n"<<(int)avg<<"\n";
cout<<"Your Register Number is:\n"<<reg<<"\n";
}
};
If you want 4.4 to be displayed as 4, and 4.5 as 5 use this hack:
avg = avg + 0.5;
cout << (int)avg << "\n";

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

What of lack this program? (sorting with qsort, struct array)

I'm create Fraction Struct Array Sorting program.
a little number (slightly under 1000) my program have good answer
but big number (slightly over 100000) my program have wrong answer
what's the problem?
this is my source and input data
#include <cstdlib>
#include <iostream>
using namespace std;
struct Fraction {
long long denominator;
long long numerator;
};
int compare(const void *a, const void *b) {
const struct Fraction *x = (Fraction *)a;
const struct Fraction *y = (Fraction *)b;
long long val = x->numerator * y->denominator - x->denominator * y->numerator;
if (val == 0) {
return x->numerator - y->numerator > 0 ? 1 : -1;
} else {
return val;
}
}
Fraction setOfData[100000];
int numOfData, numOfK;
int main() {
cin >> numOfData >> numOfK;
for (int i = 0; i < numOfData; ++i) {
long long denominator;
long long numerator;
cin >> numerator >> denominator;
setOfData[i].numerator = numerator;
setOfData[i].denominator = denominator;
}
qsort(setOfData, numOfData, sizeof(Fraction), compare);
cout<< setOfData[numOfK - 1].numerator << ' ' << setOfData[numOfK - 1].denominator;
return 0;
}
and this is my input data
input data
7 4
56783 9765493
56786 9765492
56788 9765491
8888888 9765464
56687 9765395
56789 9765497
56785 9765496
sorting standard is non-decreasing
over input data my program print
8888888 9765464
56687 9765395
56783 9765493
56785 9765496
56786 9765492
56788 9765491
56789 9765497
what's the lack of this program? is it long long? or int?
help me plz...
Try this in compare
return val > 0 ? +1 : -1;
I expect that you are losing precision when the long long int is converted to an int when you return from compare.