How to reduce/simplify fractions completely (C++) - c++

I cannot for the life of me fathom why I'm getting infinite values returned when I input a normal fraction into the code. Everything but the GCD (Greatest common divisor) seems to be working.
Is there a blatantly obvious logic error somewhere within this?
I've done my research and found various answers to the question, I mean Wikipedia even GIVES YOU code to do it, but I'd like to figure out how to make it work the way I've coded it the way it is now.
#include <iostream>
#include <stdlib.h>
#include <cmath>
#include <math.h>
using namespace std;
class Fraction
{
private:
double num;
double den;
double fraction;
double temp;
public:
void setNum();
void setDen();
int getNum();
int getDen();
void lcdOutput();
void decOutput();
int gcd();
};
void Fraction::setNum(){
cout << "Enter a value for your numerator: " << endl;
cin >> num;
}
void Fraction::setDen(){
cout << "Enter a value for your denominator: " << endl;
cin >> den;
}
int Fraction::getNum(){
return num;
}
int Fraction::getDen(){
return den;
}
int Fraction::gcd(){
Fraction set;
if(num > den){
if(fmod(num, den) == 0){
den = temp;
return temp;
}
else{
den = fmod(num, den);
set.gcd();
}
}
else{
if(fmod(den, num) == 0){
num = temp;
return temp;
}
else{
num = fmod(den, num);
set.gcd();
}
}
}
void Fraction::lcdOutput(){
Fraction set;
set.gcd();
num = num / temp;
den = den / temp;
cout << "Fraction in lowest terms: " << num << "/" << den << endl;
}
void Fraction::decOutput(){
double decimal = num / den;
cout.precision(4);
cout << "The fraction in decimal form is: " << decimal << endl;
}
int main(){
Fraction set;
set.setNum();
set.setDen();
set.getNum();
set.getDen();
set.lcdOutput();
set.decOutput();
return 0;
}

Here's what I can determine just by stepping through your code.
Starting at main, you instantiate an instance of type Fraction named set. You assign its numerator and denominator via calls to set.setNum() and set.setDen(). The calls to getNum() and getDen() do nothing in this case, as they are not being assigned to anything.
Then you call lcdOutput(), so let us begin stepping through that.
You begin by instantiating a LOCAL instance of Fraction (not sure why you want to do this, it appears to me that this may be a conceptual mistake), and then call set.gcd() for that local instance. Calling set.gcd() will call the method for THAT INSTANCE, and it seems to me that what you really want is this->gcd() or simply gcd().
You follow up by setting num = num / temp and den = den / temp, but temp is still uninitialized at this point. If the variable is left uninitialized, it can (and usually is) pointing to garbage. This probably explains why you are getting nonsensical values returned.

I went back and figured it out on my own. I saw some of the comments and noticed my very large conceptual and logical errors. Here's to anyone that has the same question!
int gcd(double num, double den){
if(den == 0){
return num;
}
return gcd(den, fmod(num, den));
}
void Fraction::lcdOutput(){
double temp = gcd(num, den);
cout << "Fraction in lowest terms: " << num / temp << "/" << den / temp << endl;
}

Related

c++ runtime error with code (classes/constructors)

I seem to be getting two errors:
A) The first iteration of the loop prints out values fine, however if I press 'y' to go for round 2 it autofills the first number as '0/0'. Shown in the image
B) I want to use the third constructor to set numerator = num and denominator = den However, it just seems to set to default values so I made a temporary fix by commenting out the constructor "Rational(num, den)" and physically wrote out numerator = num; and denominator = den;
Any help is appreciated!
// Add appropriate headers
#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;
public:
// ToDo: Default Constructor
Rational();
// ToDo: Constructor that takes int numerator
Rational(int i);
// ToDo: Constructor that takes int numerator and int denominator
Rational(int p, int q);
// 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();
// ToDo: declare an accessor function to get the numerator
int getNumerator();
// ToDo: declare an accessor function to get the denominator
int getDenominator();
// 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*d)
void sum(Rational a, Rational b);
// test if two rational numbers are equal.
bool isEqual(const Rational& op);
};
int main()
{
// ToDo: declare three rational objects using the default constructor
Rational a, b, c;
char answer='Y';
// Main loop to read in rationals and compute the sum
do {
cout << "\nEnter op1 (in the format of p/q): ";
a.input();
//Debug line
a.output();
// ToDo: use your input member function to read the first rational
cout << "\nEnter op2 (in the format of p/q): ";
// ToDo: use your input member function to read the second rational
b.input();
//Debug line
b.output();
// ToDo: use the third rational to call Sum with first and second as parameters
c.sum(a, b);
cout << "\nThe sum of op1 and op2 is: ";
c.output();
// ToDo: ouptput the third rational
cout << endl;
cout << "\nTry again (Y/N)?";
cin >> answer;
} while (answer == 'y' || answer == 'Y');
// ToDo: test getters
cout << "\nC's numerator is: " << c.getNumerator() << endl;
cout << "\nC's denominator is: " << c.getDenominator() << endl;
// TODO: Use two constructors to declare a whole number 3/1 and a 4/5
// TODO: Use output to print both rationals
//cout << .output() << " " << .output() << endl;
return 0;
}
// ToDO: Implement your class member functions below.
Rational::Rational()
{
numerator = 0;
denominator = 1;
}
Rational::Rational(int i)
{
numerator = i;
denominator = 1;
}
Rational::Rational(int p, int q)
{
numerator = p;
denominator = q;
}
void Rational::sum(Rational a, Rational b)
{
int num = (a.numerator*b.denominator + a.denominator*b.numerator);
int den = (a.denominator*b.denominator);
numerator = num;
denominator = den;
}
void Rational::input()
{
string in;
int num,den;
//cout << "Enter a rational number in the form of x/y : ";
getline(cin, in);
// find the index position of /
int indx = in.find("/");
// seperator out the numerator
num = atoi(in.substr(0, indx).c_str());
// seperate out the denominator
den = atoi(in.substr(indx+1, in.length()).c_str());
// Rational(num, den);
//cout <<num << " " <<den << endl; // Debug Line
numerator = num;
denominator = den;
//cout <<numerator << " " <<denominator << endl; // Debug Line
}
void Rational::output()
{
cout << numerator << "/" << denominator;
}
// Two getter functions
int Rational::getNumerator()
{
return numerator;
}
Here is the solution. Let me know if you don't know what Buffer is or why do we flush it. I'll try to explain further.
cout << "\nTry again (Y/N)?"; //In main
cin >> answer;
cin.ignore(256,'\n'); // Flush the buffer
Here is the explanation.
Yeah, it(cin) will work fine, As cin doesn't have any issue with buffer. But the issue is with getline. Now let's explain why. First, you need to know how the computer takes input in the program. Whenever you cin some value like cin>>x. The value doesn't directly go into x. Firstly it is stored in some temporary location named buffer. That's why you can press backspace on your console. If it directly writes in more variable(memory), you can't press backspace. It means suppose entering string you wrote "appke", but you want to write "apple " you can press backspace(until you haven't pressed enter). Now, what happens you take input with cin as you give input and press Enter for the next input. Like in your case you pressed "y" and then enter(which is denoted by "\n"). So as enter data it goes into the buffer and then you press enter that enter also goes into buffer but system picks only data from buffer like "y" in your case. So your buffer still has "\n" from previous data. Now come to getline. It has one parameter named "delim" [See-here]http://www.cplusplus.com/reference/string/string/getline/ who tells getline when to stop taking input. By default its values is "\n". Now from your previous entry, your buffer has already "\n" in it. So as getline comes in contact with the buffer, it sees "\n", and it thinks that data for input is present as he finds "\n" in the buffer which is the indicator when to stop. That's why it didn't ask for input. Now come to a solution. If ever you think to use getline after cin. All you need to do is to remove "\n" from the buffer. So all you do is cin.ignore("\n"). You are asking cin to ignore "\n" which was present in the buffer. So when control goes to getline. It ignores the already present "\n" in the buffer and works normally.

Getting strange value

I'm currently learning about functions in C++ and am currently working on a homework assignment with functions being the main thing.
Currently, I'm trying to make a grade calculator with every operation of the process being split into a function of its own.
Here's the code:
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
using namespace std;
void getHWGrades(int homeworks[], int size)
{
cout << "\nEnter the grades, out of 100 points, for the 9 homeworks you completed." << endl;
cout << "Note that Homework 10 is given to you for free, but is the same grade \nas homework 9.\n" << endl;
for (int i = 0; i < 9; i++)
{
cout << "Homework " << i + 1 << ": ";
cin >> homeworks[i];
while (homeworks[i] > 100 || homeworks[i] < 0)
{
cout << "Invalid grade, input homework grade again: ";
cin >> homeworks[i];
}
}
homeworks[9] = homeworks[8];
cout << "Homework 10: " << homeworks[9];
}
double quizAverage()
{
double quizPts;
cout << "Input your in class quiz average: ";
cin >> quizPts;
return quizPts;
}
double labAverage()
{
double labPts;
cout << "Input your lab average: ";
cin >> labPts;
return labPts;
}
double teamProject()
{
double teamPts;
cout << "Input your team project grade: ";
cin >> teamPts;
return teamPts;
}
int exam1()
{
int exam1Pts;
cout << "Input your exam1 grade: ";
cin >> exam1Pts;
return exam1Pts;
}
int exam2()
{
int exam2Pts;
cout << "Input your exam2 grade: ";
cin >> exam2Pts;
return exam2Pts;
}
double hwAverage(int homeworks[], int size)
{
double total = 0;
double homeworkAverage = 0;
for (int i = 0; i < size; i++)
{
total = total + homeworks[i];
}
homeworkAverage = (total*1.0) / 10;
return homeworkAverage;
}
double currentPoints(double& quizPts, double& labPts, double& teamPts, double& homeworkAverage, int& exam1Pts, int& exam2Pts)
{
double totalPts = ((quizPts / 100.0) * 10) + ((labPts / 100.0) * 10) + ((teamPts / 100.0) * 15) + ((homeworkAverage / 100.0) * 20) + ((exam1Pts / 100.0) * 10) + ((exam2Pts / 100.0) * 15);
cout << "\nYour current points (out of the 80 total available), stand at: " << totalPts;
return totalPts;
}
double currentAverage(double& totalPts)
{
double availableAverage = totalPts*(100.0 / 80);
cout << "\nYour current average is: " << availableAverage;
return availableAverage;
}
int main()
{
// keep the console from closing in visual studio
char charer;
double totalPts;
double quizPts, labPts, teamPts, homeworkAverage;
int exam1Pts, exam2Pts;
const int ARRAY_SIZE = 10;
int hwArray[ARRAY_SIZE];
getHWGrades(hwArray, ARRAY_SIZE);
quizAverage();
labAverage();
teamProject();
exam1();
exam2();
currentPoints(quizPts, labPts, teamPts, homeworkAverage, exam1Pts, exam2Pts);
currentAverage(totalPts);
cin >> charer;
}
My issue, which I believe lies in the functions currentPoints and currentAverage, is that when I run this totalPts outputs as -5.09078e+61 and as a follow up result with the currentAverage function, availableAverage outputs as -1.157e+62.
I'm sure that the issue has to do with how I'm passing the values from function to function (which I doubt I'm doing correctly).
How would I go about fixing this issue?
Thank you in advance.
You need to store the return value from currentPoints() function, like this.
totalPts = currentPoints(quizPts, labPts, teamPts, homeworkAverage, exam1Pts, exam2Pts);
currentAverage(totalPts);
Reason is, you declared "totalPts" as local variable in currentPoints().
"Local variables has function scope only, it is undefined to main function".
Do this for all other
functions(quizAverage,labAverage,teamProject,exam1,exam2, hwAverage,currentAverage)
I hope, this will solve the issue !!!
The problem is not about functions, it's about variables.
Let's take quizPts for instance:
In the main method, you declare this variable, but then you don't do anything with it before sending it to currentPoints. Therefore it has an undefined value when you do so (undefined often looks like random in C).
The other variable quizPts you use in quizAverage have the same name but is not the same for the compiler.
Try in your main:
quizPts = quizAverage();
You asked
How would I go about fixing this issue?
And the answer is "Use the debugging tool with "watches" window open in your favorite IDE".
It's always very difficult to find an error simply by re-reading the code, but in the debugger you can see all the values of your variables at each moment of time. Specifically, in this example, you would realize that your variables have garbage values from the very beginning (are not initialized), and this value never changes.
Using this approach you could find the reason yourself in time less than necessary to write this SO question. I hope this will help you to save your time in future.
The problem is you use the variables such as quizPts and labPts without storing any value in them. In your case, you have to store the return value of the function to the corresponding variable before using it. For example, do the same as the following statement:
quizPts = quizAverage();

Print function in a class not updating when boolean is updated

So I have a program for a class that Im writing that is all done except for the print function. The input function is correct and the boolean value will update in the input function but when i try to transfer to the print function it always prints (-) and if the user enters 'Y' then it is suppose to bypass the (-) and just print out the fraction. If anyone has anyway to get it to work, I feel like ive tried everything.
Edit: The print function works when i print out just the two fractions in main which are f1 and f2 but the problem is coming when passing the positive into the print function i believe.
class fraction
{
private:
int numerator;
int denom;
bool positive;
public:
void inputFrac();
void printFrac();
fraction fracMult(fraction& b);
fraction fracDiv(fraction& b);
fraction fracAdd(fraction& b);
fraction fracSub(fraction& b);
};
void fraction::printFrac()
{
if (positive=true)
{
cout << "-" << numerator << " / " << denom;
}
else
{
cout << "+" << numerator << " / " << denom;
}
}
void fraction::inputFrac()
{
char tempchar1;
fraction tempchar;
cout<<"Please input the numerator ";
cin>>numerator;
cout<< "Please input the denominator ";
cin>>denom;
cout<<"Is the fraction positive? (Y or N) ";
cin>>tempchar1;
if((tempchar1=='Y'))
{
positive=true;
}
else
{
positive=false;
}
}
You're assigning within your if statement.
Change:
if (positive=true)
to:
if (positive==true)
In your printFrac function, you have if (positive=true). This is incorrect, for what you are doing. You should instead have if (positive) {/*stuff*/}.

New to c++, not returning value after function, calc.cpp

I have a basic issue that hopefully someone here can help me with. I'm quite confident it's a small, forgetful type of issue, missing return or something similar.
///////////////////////////
//My Basic Calculator App
//Written by l8nit3tr0ubl3
//of NottaDev inc.
///////////////////////////
#include <iostream>
void in() //Take input from user, all 3 variables.
{
int add(int, int); //Forward declarations
int minus(int, int);
int divide(int, int);
int multiply(int, int);//end declarations
std::cout << "My Basic Calculator\n";//take inputs
std::cout << "Please input your first number.\n";
int firstNumber;
std::cin >> firstNumber;
std::cout << "Choose math function.\n";
std::cout << "Eg. *-+/\n";
char operatorType;
std::cin >> operatorType;
std::cout << "Please input second number.\n";
int secondNumber;
std::cin >> secondNumber;//end inputs
if (operatorType == '+') //determine math function to use
add(firstNumber, secondNumber);
else if (operatorType == '-')
minus(firstNumber, secondNumber);
else if (operatorType == '/')
divide(firstNumber, secondNumber);
else if (operatorType == '*')
multiply(firstNumber, secondNumber);//end math function
}
int add(int firstNumber, int secondNumber) //Actual math is done
{
return firstNumber + secondNumber;
}
int minus(int firstNumber, int secondNumber)
{
return firstNumber - secondNumber;
}
int divide(int firstNumber, int secondNumber)
{
return firstNumber / secondNumber;
}
int multiply(int firstNumber, int secondNumber)
{
return firstNumber * secondNumber; //End math
}
int main()
{
in(); //Call input, which will call math function
return 0; //return '0' for no error.
}
Can somebody please tell me what ive forgotten to call or return??
I should have been more precise on my question and i apologize for not doing so. There are no errors produced, i was simply unable to echo my answer to console. However there is a perfect answer supplied below
Your add, multiply etc. functions return the result of the operation, but you're not doing anything with it.
You could for example print it:
std::cout << add(firstNumber, secondNumber) << std::endl;
Probably you want to output the result of your calculations.
So write
std::cout << add(firstNumber, secondNumber);
But even nicer it is, if you do the output only once. For this use a temprary variable, for example
result = add(firstNumber, secondNumber);
...
std::cout << "The result is " << result << std:endl;
Your add, multiply and minus functions are returning back to void in(), and you have no variable assigned to them when they are returned.

probability calculator with factorial equation

I have to make a code that calculates the probability of winning the lottery given the amount of numbers there are to choose from and how many you must choose. I must use the factorial equation (n!)/(k!*(n-k)!) in the code. The code itself works fine, but the equation will not compile.
//This program calculates the probability of winning the lottery
#include <iostream>
using namespace std;
double factorial(int n, int k);
int main()
{
//variables
int n;
int k;
char pa;
int chance;
double prob;
//loop
do
{
cout << "How many numbers (1-12) are there to pick from?\n" << endl;
cin >> n;
if(n>12 || n<1)
{
cout << "Invalid entry.\nHow many numbers (1-12) are there to pick from?\n";
cin >> n;
}
cout << "How many numbers must you pick to play?\n";
cin >> k;
if(k>n || k<1)
{
cout << "Invalid entry.\nHow many numbers must you pick to play?\n";
cin >> n;
}
cout << "Your chance of winning the lottery is 1 in " << chance << endl;
prob=factorial( n, k);
cout << "This is a probability of " << prob << endl;
cout << "Play again?";
cin >> pa;
} while (pa != 'n');
return 0;
}
double factorial(int n, int k)
{
double fact;
fact=(n!)/(k!*(n-k)!);
return fact;
}
There is no ! operator in C++ in the meaning of a factorial operation, and your factorial function is not calculating a factorial. (The ! operator is typically a logical NOT operator.)
This is how one would write a factorial method,
int factorial(int n) {
return (n <= 1 ? 1 : n * factorial(n - 1));
}
The method is recursive and is operating on integers - you may need to consider whether this is suitable for your task
Then your original function should be renamed along the lines of double choice(int n, int k) and use the new factorial implementation.
You cannot write n! and expect it to calculate the factorial of n.
Change fact=(n!)/(k!*(n-k)!) to fact=f(n)/(f(k)*f(n-k)), and add the following function:
unsigned long long f(int n)
{
unsigned long long res = 1;
while (n > 1)
{
res *= n;
n--;
}
return res;
}
BTW, you have several other problems within your code:
You are using variable chance without initializing it.
Function factorial does not return the probability, but the number of different choices. This is an integer value, and you might as well use unsigned long long instead of double for it. The probability is the inverse of the value (1/value), so you should change your printed message accordingly.