Change Calculator Not Calculating Pennies - c++

I just finished my change calculator (Calculates change based on cost of purchase and cash given). I was testing it to see if it works and found one bug. Whenever the amount of pennies to be given is exactly one, it says it is 0. I went through the code and did the math manually off the code I wrote (without running it) and it looks like it should work. If you want to test this yourself just put in 0 as the cost of the purchase and 36.91 as the cash given. (This means the change is 36.91 and it should be 1 twenty, 1 ten, 1 five, 1 half dollar, 1 quarter, 1 dime, 1 nickel, and 1 penny [but it says 0 pennies].
Due note: I am very new to C++ and know VERY little
Here is the code:
/*This program simulates a situation at the register where someone pays with cash
and the cashier needs to know how much change and of which coins he or she needs to give.
Written by Jay Schauer
*/
//Data Declarations
#include <iostream>
#include <cstdint>
int main()
{
using namespace std;
double cost; //Stores cost of purchase
cout << "Input cost of purchase (in USD)" << endl;
cin >> cost;
double cash; //Stores cash that pays for purchase
cout << "Input cash given (in USD)" << endl;
cin >> cash;
double changet = cash - cost; //Stores the change,
the t is for temporaary because I use a different change variable later
cout << "Change to be given is " << changet << " in..." << endl;
//Also, I thought this was pretty clever since doubles apparantly can't be used
//with modulus (it gave me an error),
//so I figured I just multiply it by 100 and multiply all the divisions by 100 also
changet *= 100;
int change = changet; //Converts changet to an integer to be used with the modulus
int coins; //Stores the amount of "coins" to be given as change
coins = change / 2000;
cout << coins << " twenty dollar bills" << endl;
change = change % 2000;
coins = change / 1000;
cout << coins << " ten dollar bills" << endl;
change = change % 1000;
coins = change / 500;
cout << coins << " five dollar bills" << endl;
change = change % 500;
coins = change / 100;
cout << coins << " one dollar bills" << endl;
change = change % 100;
coins = change / 50;
cout << coins << " half dollars" << endl;
change = change % 50;
coins = change / 25;
cout << coins << " quarters" << endl;
change = change % 25;
coins = change / 10;
cout << coins << " dimes" << endl;
change = change % 10;
coins = change / 5;
cout << coins << " nickels" << endl;
change = change % 5;
//There is one problem that I can't figure out
//If the number of pennies to be given for change is exactly 1,
//it says 0 for the number of pennies to be given as change
coins = change / 1;
cout << coins << " pennies" << endl;
system("pause");
return 0;
}

Unfortunately you've stubled across one of the common problems with using double and floating point values. They aren't exact. They are good enough for rock and roll, but when you want exact, wellll....
OK so you have 36.91... sort of. It's really something like 36.90999999999.
You multiply it by 100 and get 3690.999999999.
You convert it into an integer and get truncated to 3690. The fraction is completely discarded.
You should be able make it work here by rounding .
int change = std::round(changet);

This code is relying on integer division, when you should be using floating-point division. In short, you are truncating the decimal portions of your answers.
Let's step through, using your input of $36.91. First, with $20 bills:
coins = change / 2000; -> coins = 3691 / 2000; -> coins = 1.8455;
since we are dealing with integers, this falls into integer division and coins is actually set to 1. One $20 bill is due as change.
Moving on, for $10 bills:
change = change % 2000; -> change = 3691 % 2000; -> change = 1691;
coins = change / 1000; -> coins = 1691 / 1000; -> coins = 1.691;
again, this falls into integer division, so 1.691 is truncated and coins is set to 1. The program will indicate that one $10 bill is due.
Now, for $5 bills...
change = change % 1000; -> change = 1691 % 1000; -> change = 691;
coins = change / 500; -> coins = 691 / 500; -> coins = 1.382;
The decimal component of 1.382 is, again, dropped, and coins is set to 1. That's one $5 bill.
change = change % 500; -> change = 691 % 500; -> change = 191;
coins = change / 100; -> coins = 191 / 100; -> coins = 1.91;
1.91 is truncated to 1. That's one $1 bill.
change = change % 100; -> change = 191 % 100; -> change = 91;
coins = change / 50; -> coins = 91 / 50; -> coins = 1.82;
Again, that's truncated. 1.82 is cast to an integer set to 1. One half-dollar.
change = change % 50; -> change = 91 % 50; -> change = 41;
coins = change / 25; -> coins = 41 / 25; -> coins = 1.64;
One quarter.
change = change % 25; -> change = 41 % 25; -> change = 16;
coins = change / 10; -> coins = 16 / 10; -> coins = 1.6;
One dime.
change = change % 10; -> change = 16 % 10; -> change = 6;
coins = change / 10; -> coins = 6 / 5; -> coins = 1.2;
One nickel.
change = change % 5; -> change = 6 % 5; -> change = 1;
coins = change / 1; -> coins = 1 / 1; -> coins = 0.9999999999999;
Zero pennies.
The reason for this is how binary arithmetic handles division. There is a loss of precision that is causing 0.9999999 to be calculated, which when truncated will result in zero pennies.
Your solution: Since dividing something by 1 yields that same something (identity), take coins = change / 1; out of your program.
Also, search for an article on floating point arithmetic.

Related

Not understanding why code isn't producing desired answer

The assignment I've been given is asking me to find out how many trees can be put in a certain length and how much total space they'd take up including the required space between the trees. Thanks to some help I've been able to get the tree total correct, but the total space taken up is incorrect. What can I do to fix this.
input is: length = 10, TRadius = .5, ReqSpace = 3
desired output is: TreeTot = 2
Total space should be 1.57
Actual output is: TreeTot = 2 Total Space is 6.1
Here is the code I'm using.
#include <iostream>
#include <iomanip>
using namespace std;
const double PI = 3.14;
int main()
{
double length;
double TRadius;
double ReqSpace;
int TreeTot = 0;
cout << "enter length of yard: ";
cin >> length;
cout << "enter radius of a fully grown tree: ";
cin >> TRadius;
cout << "required space between fully grown trees: ";
cin >> ReqSpace;
while (length > TRadius * 2 + ReqSpace) {
TreeTot += 1;
length -= (TRadius * 2) + ReqSpace;
}
cout << "The total space taken up is ";
cout << setprecision(2) << TreeTot * TRadius * PI + ReqSpace << endl;
cout << "The total amount of trees is ";
cout << TreeTot;
return 0;
}
These two lines:
TreeTot + 1;
length - (TRadius * 2) + ReqSpace;
are valid statements, but they're just expressions. You calculate a value, but don't do anything with it. TreeTot + 1... and then what? You need to assign the calculated value to something. Presumably you're wanting to increase the TreeTot and decrease the length. Just assign the values like so:
TreeTot = TreeTot + 1;
length = length - (TRadius * 2) + ReqSpace;
Or use the shorthand for modifying and assigning the result to the same value:
TreeTot += 1;
length -= (TRadius * 2) + ReqSpace;
Your answer will probably still be wrong because the if-statement only runs once - you never tell it you want it to do the code within multiple times. If you change the if to a while then the code will loop until length is too small to satisfy the condition.

how to avoid the loss of precision when trying to round number? (C++)

just finished my first week of C++(using Visual Studio 2017), I wrote a program that asks the user for the amount of money and will print the number of bills and coins. it works at the beginning, but sometimes it just prints wrong number.(when the user input $1.28, it shows 1 dollar, 1 quarter and 2 pennies.)
here is my code, is there anything wrong? the algorithm or the data type?
#include<iostream>
using namespace std;
float Q = 0.25;
float D = 0.10;
float N = 0.05;
float P = 0.01;
float Dollar = 1;
float money;
float dollars, quarters, dimes, nickels, pennies;
int main() //to break money into coins.
{
cout << "how many money do u have?" << endl;
cin >> money;
dollars = (int)money;
quarters = (int)((money - dollars*Dollar)/Q);
dimes = (int)((money - dollars*Dollar - quarters*Q) / D);
nickels = (int)((money - dollars*Dollar - quarters*Q - dimes*D) / N);
pennies = (int)((money - dollars*Dollar - quarters*Q - dimes*D - nickels*N) / P);
cout << "$" << money << " can be break into :" << endl;
cout << dollars << " dollars. " << endl;
cout << quarters << " quarters. " << endl;
cout << dimes << " dimes. " << endl;
cout << nickels << " nickels. " << endl;
cout << pennies << " pennies. " << endl;
}
how to avoid the loss of precision when trying to round number? (C++)
When you convert from floating point to integer, the fractional part is truncated. To ensure no loss of integer precision (getting the right "whole"), add 0.5 to the result each time e.g:
quarters = static_cast<int>(((money - dollars*Dollar)/Q)+0.5);
This however doesn't work when the result is negative e.g:
50.5 - 100 = -49.5 -> +1 = -48.5 -> -48... not 49
For negatives you would want to therefore subtract 0.5.
I'd assume, that in the line
pennies = (int)((money - dollars*Dollar - quarters*Q - dimes*D - nickels*N) / P);
the part (money - dollars*Dollar - quarters*Q - dimes*D - nickels*N) will produce a value, that is not exactly .03, but a tad below. This is due to the nature of floating point arithmetic, you should read on that. Given that it's something like .029999999995, division by .01 will not yield 3.0, but maybe 2.9999999995. Since you are not rounding, but casting the value to an integer, the whole part after the period will be thrown away, hence it results in 2 pennies.
How can you solve this issue?
The simplest thing will be to round the value instead of casting it, this should yield the correct value, but this is kind of a hacky solution to an issue there is an exact solution for. You could also try to use double instead of a float, but this, too, would not solve the issue. You might get this correct, but the same a similar bug could still occur.
Store whole pennies
You could store the whole amount as an integer (whole pennies)
int amountInPennies;
int penniesPerDollar = 100;
int penniesPerQuarter = 25;
int penniesPerDime = 10;
int penniesPerNickle = 5;
int totalDollars = amountPennies / penniesPerDollar;
int totalQuarters = (amountPennies - totalDollars * penniesPerDollar) / penniesPerQuarter;
...
Decimal types
In a real world application dealing with money (well, depending on the type) you'd most likely go with some kind of decimal type instead of a float. According to this answer there are libraries with arbitrary precisions arithmetic available under the GNU license. You could still roll your own decimal type, that - more or less - does what I presented in the first approach. This might be a great excercise to learn, but maybe a ready-made library would be the better option when it comes to a real world application.

Variable percentage displaying zero value

Hey guys i have a bug that i am unable to detect. Kindly help me out. In this code i want to calculate a percentage but after the calculation there is a zero value store in the variable "percentage"
int _tmain(int argc, _TCHAR* argv[])
{
int total_marks, obtained_marks, percentage;
total_marks = 1100;
cout << "enters yours obtained marks"<<endl;
cin >> obtained_marks;
percentage = (obtained_marks / total_marks) * 100;
cout << "yours percentage =" << percentage;
if (percentage >= 60)
{
cout << "you have passed with first division";
}
cout << "yours pecentage is=" << percentage;
system("pause");
return 0;
}
Integer division truncates towards zero.
Given
int total_marks, obtained_marks, percentage;
and
percentage = (obtained_marks / total_marks) * 100;
if obtained_marks is less than total_marks, the value of (obtained_marks / total_marks) will be zero. In that case,
percentage = (obtained_marks / total_marks) * 100;
will also be zero.
Even
percentage = (obtained_marks / total_marks) * 100.0;
will be zero, because the value in the parenthesis is still zero.
One better way would be:
percentage = ( 100 * obtained_marks ) / total_marks;
obtained marks and total marks are integers so you are getting zero when you divide. Change your data types to float or double.

Having garbage numbers while calculating percentage

So, I hate to ask, but, I'm having some issue with this, I'm new to C++ and I'm just starting out. Everything is done for the most part. Expect for a little thing.
Line 35-36 should be calculating the average (Which for some reason, I haven't been able to get it to work.)
Line 41-47 should print out the percentage that heads/tails was landed on with precision to one decimal, and then print out the correct numbers of * to represent the percentage.
But, when I run it, my heads/tail count is messed up. As well as my percentage numbers. I'm just looking for a push in the right direction.
#include <cstdlib>
#include <iostream>
#include <ctime>
#include <iomanip>
using std::cout; using std::cin; using std::endl;
using std::fixed; using std::setprecision;
int main()
{
srand(time(0));
int userInput,
toss,
headsCount,
tailsCount;
double headsPercent = 0,
tailsPercent = 0;
cout << "How many times do you want to toss the coin? ";
cin >> userInput;
while(userInput < 0)
{
cout << "Please enter a positive number: ";
cin >> userInput;
}
for(int i = 1; i < userInput; i++)
{
toss = rand() % 2;
if(toss == 0)
headsCount++;
else
tailsCount++;
}
headsPercent = userInput / headsCount * 100;
tailsPercent = userInput / tailsCount;
cout << "Heads: " << headsCount << endl
<< "Tails: " << tailsCount << endl << endl;
cout << "Heads Percentage: " << fixed << setprecision(1) << headsPercent << " ";
for(int b = 0; b < headsPercent; b++)
cout << "*";
cout << "\nTails Percentage: " << tailsPercent << " ";
for(int b = 0; b < tailsPercent; b++)
cout << "*";
return 0;
}
In addition to the uninitialized variables here, that others have pointed out, the calculations are all wrong.
Take out paper and pencil, and run some your own calculations the old-fashioned way.
Let's say there were five tosses, three heads, two tails. This means that (after fixing the uninitialized variables):
userInput=5
headsCount=3
tailsCount=2
Now, here's how you're calculating your supposed percentages:
headsPercent = userInput / headsCount * 100;
tailsPercent = userInput / tailsCount;
So, using your own numbers, you will get:
headsPercent = 5 / 3 * 100
tailsPercent = 5 / 2;
Does this look right to you? Of course not. You can do the arithmetic yourself. Divide 5 by 3 and multiply by 100. This is integer division, so five divided by three is 1, multiplied by 100 is 100. Five divided by two is two. So you get 100% and 2% here.
Of course, that's wrong. Two and three times, out of five, is 40% and 60%, respectively.
Writing a program means:
A) Figure out how calculations need to be made
B) Write the code to do the calculations.
You're still on step A. You need to figure out how you want to make these calculations so they're correct, first.
This has nothing really to do with C++. If you were using any other language, and coded this, in that manner, you'll get the same wrong answers.
The only thing this might have to do with C++ is that integer division, in C++ does not produce a fractional amount. It's integer division. But that's not your only problem.
Firstly u have to correct ur basics of mathematics.
Calculating %age means
example
(Marks obtained)/(Total marks)*100
Not (Total marks/marks obt)*100
Dividing any no by 0 is not defined. So if ur current code randomly assign toss or head =0, then obviously u will have errors.
Secondly talking about codes, U should either initialize i from 0 , or u should use
for (i=1; i<=userInput; i++)
As otherwise the head+toss value will be userInput-1.
Also remember to initialise variables like
Int headsCount=0;
etc. As the variable will take any random value if not initialised to a fixed no. (Though it does not creates a problem here)
And just change the datatype
int userInput,
toss,
headsCount,
tailsCount;
To
double userInput,
toss,
headsCount,
tailsCount;
This will solve your problem.
Advice: Please use
using namespace std;
in the starting of ur programs as u have to type a lot of std::
Welcome to C++. You need to initialise your variables. Your compiler should have warned you that you were using a variable without initialising it. When you don't initialise a value, your program has undefined behaviour.
I'm talking about headsCount and tailsCount. Something like this should be fine:
int headsCount = 0, tailsCount = 0;
Also note that your loop should start at 0, not 1, since you are using the < operator on the final condition.
Finally, your percentage calculations are backwards. It should be:
headsPercent = headsCount * 100 / userInput;
tailsPercent = tailsCount * 100 / userInput;
Now, there's a weird thing that might happen because you are using integer division. That is, your percentages might not add up to 100. What's happening here is integer truncation. Note that I dealt with some of this implicitly using the 100x scale first.
Or, since the percentages themselves are double, you can force the calculation to be double by casting one of the operands, thus avoiding integer truncation:
headsPercent = static_cast<double>(headsCount) / userInput * 100;
In fact, since the only two possibilities are heads and tails, you only need to count one of them. Then you can do:
tailsPercent = 100 - headsPercent;
1) This loop should start from 0:
for(int i = 1; i < userInput; i++)
2) The divisions are not correct:
//headsPercent = userInput / headsCount * 100;
//tailsPercent = userInput / tailsCount;
headsPercent = headsCount / userInput * 100;
tailsPercent = tailsCount / userInput * 100;
3) Finally:
cout << "\nTails Percentage: " << fixed << setprecision(1) << tailsPercent << " ";

Sum finder not consistent

My code here finds the sum of some given multiples less than or equal to a certain number. It uses a modified version of a formula I read about on the internet a while ago (the one for finding the sum of all the numbers less than or equal to 100, or 1000 or something- when I wrote my formula while I was waiting to be picked up at the ymca so it might not look like the one from the internet). So for me I used (n+x)(n/x/2), where n is the limit (for example 1000), and x is the multiple you are using (so 1, or 3, or 5). So if n = 1000 and x = 5, it should find the sum of all multiples of 5 less than or equal to 1000).
Sometimes it adds up correctly and sometimes it doesn't.
For example, if I choose 1 and 2 as the multiples, and 20 as the limit, it prints out 320 (which is correct if you add 1+2+3...+20 and then add to that 2+4+6...+20).
But if I do the multiples of 3 and 5 and 1000 as the limit, it prints out 266,998 (which is wrong according to the internet).
I do not understand why it worked in the first instance but not the second (I have only taken 1 year of high school math, I'll be a sophomore).
Here is the code:
/*
Finds the sum of all inputted multiples below a certain number
For example, it could find the sum of all the multiples of 3 and 5 less than
or equal to 1000
Written By Jay Schauer
*/
//Data Declarations
#include <iostream>
int main()
{
using namespace std;
int a; //Stores the number of multiples being used
cout << "Enter the amount of multiples you would like to use (up to 50
<< endl;
cout << "(for example, enter '2' if you would like to use two multiples,
maybe 3 and 5?)" << endl;
cin >> a;
cout << "Next, you will enter the mutliples you want to use." << endl;
cout << "(for example, if you want to find the sum of the multiples of 3
and\n5 below a given amount, enter 3 as 'multiple 1' and 5 as 'multiple
2')" << endl;
int multiples[50]; //Stores the multiples being used
for (int i = 0; i < a; i++)
{
cout << "Enter 'multiple " << (i + 1) << "'" << endl;
cin >> multiples[i];
}
int limit; //Stores the limit
cout << "Enter the the limit for how high you want to add the multiples
<< endl;
cout << "(for example, you could set the limit to 1000 to find the sum
of the\nmultiples of 3 and 5 (if you entered those) less than and or
equal to 1000)" << endl;
cin >> limit;
int sum(0); //Stores the sum
for (int i = 0; i < a; i++)
{
sum += ((limit + multiples[i]) * (limit / multiples[i] / 2));
}
cout << "The sum is "<< sum << endl;
system("pause");
return 0;
}
EDIT: I believe the problem might lie in the code not in the formula, because using it on multiples of 3 with 21 as the limit causes it to print out 72, not 84 like it should. I am still unsure of the coding error.
EDIT 2: I changed the for loop to this so it hopefully will function when the limit isn't a multiple of the multiple
for (int i = 0; i < a; i++)
{
int max = limit; /*This is done so I can change max in case it isn't
a multiple of the multiple*/
while (max % multiples[i] != 0) max--;
sum += ((max + multiples[i]) * (max / multiples[i] / 2));
}
Change
sum += ((limit + multiples[i]) * (limit / multiples[i] / 2));
to
sum += (limit + multiples[i]) * (limit / multiples[i]) / 2;
As it is, for your example of 3 and 21, you're computing (24 * (7 / 2)) = 24 * 3 = 72 (integer division of 7 by 2 gives 3, and the remainder is lost), but you want to be computing (24 * 7) / 2 = 84.