My task is to write a program to represent an amount of money in different coins.
UPD: I'm allowed to use <stdio.h> only, modulo and division.
The output should be:
Coin Qty Balance
-------- --- ---------
365.5700
Toonies 182 1.5700
Loonies 1 0.5700
Quarters 2 0.0700
Dimes 0 0.0700
Nickels 1 0.0200
Pennies 2 0.0000
But I'm getting this:
Coin Qty Balance
-------- --- ---------
365.5700
Toonies 182 1.5700
Loonies 1 0.5700
Quarters 2 0.0600
Dimes 0 0.0600
Nickels 1 0.0100
Pennies 1 0.0000
This is my code. I cannot get the right calculations with quarters, dimes, nickels and pennies. What have I written wrong? Maybe the issue in type casting.
#include <stdio.h>
int main() {
double total = 365.5700;
int toonies, loonies, quarters, dimes, nickels, pennies;
double balToonies, balLoonies, balQuarters, balDimes, balNickels, balPennines;
// Toonies
toonies = (int)total / 2;
balToonies = (int)(total * 100) % 200 / 100.0;
// Loonies
loonies = (int)balToonies / 1;
balLoonies = (int)(balToonies * 100) % 100 / 100.0;
// Quarters
quarters = (int)(balLoonies * 100) / 25;
balQuarters = (int)(balLoonies * 100) % 25 / 100.0;
// Dimes
dimes = (int)(balQuarters * 100) / 10;
balDimes = (int)(balQuarters * 100) % 10 / 100.0;
// Nickels
nickels = (int)(balDimes * 100) / 5;
balNickels = (int)(balDimes * 100) % 5 / 100.0;
// Pennies
pennies = (int)(balNickels * 100) / 1;
balPennines = (int)(balNickels * 100) % 1 / 100.0;
printf("Coin Qty Balance\n");
printf("-------- --- ---------\n");
printf("%22.4lf\n", total);
printf("Toonies %3d %9.4lf\n", toonies, balToonies);
printf("Loonies %3d %9.4lf\n", loonies, balLoonies);
printf("Quarters %3d %9.4lf\n", quarters, balQuarters);
printf("Dimes %3d %9.4lf\n", dimes, balDimes);
printf("Nickels %3d %9.4lf\n", nickels, balNickels);
printf("Pennies %3d %9.4lf\n\n", pennies, balPennines);
return 0;
}
What have I written wrong?
Wrong use of floating point (FP) and integer math by not considering the roundings of FP math and integer truncation and their limitations of representable values.
When a FP result is just under a whole number, like x.99999..., applying (int) results in x instead of the desired x + 1.
double cannot represent values like 365.5700 exactly. Instead a nearby value is used: 365.56999999999999317878973670303821563720703125. That is a whole number * some_power_of_2.
double * 100 often results in a rounded product.
These roundings and OP's casts which truncate result in various off-by-one calculations as compared to the desired result.
Alternative today
A simple alternative is to scale the money by the smallest unit, (which appears to be Can$0.0001 in this case) and use integer math.
Let's go with a wider type than int, so code can handle small accounts as well as large ones.
#include <math.h>
typedef long long ssymoney;
#define SSYMONEY_SCALE 10000
#define SSYMONEY_FROM_double(d) llround((d) * SSYMONEY_SCALE)
#define SSYMONEY_TO_double(m) ((double)(m) / SSYMONEY_SCALE)
#define SSYMONEY_TOONIE (SSYMONEY_SCALE * 2)
#define SSYMONEY_LOONIE (SSYMONEY_SCALE * 1)
#define SSYMONEY_QUARTER (SSYMONEY_SCALE * 25 / 100)
#define SSYMONEY_DIME (SSYMONEY_SCALE * 10 / 100)
...
int main(void) {
double total = 365.5700;
ssymoney ssytotal = SSYMONEY_FROM_double(total);
long long toonies, loonies, quarters, dimes, nickels, pennies;
ssy_money balToonies, balLoonies, balQuarters, balDimes, balNickels, balPennines;
// Toonies
toonies = ssytotal / SSYMONEY_TOONIE;
balToonies = ssytotal % SSYMONEY_TOONIE ;
// Loonies
loonies = balToonies / SSYMONEY_LOONIE;
balLoonies = balToonies % SSYMONEY_LOONIE ;
// quantity = balance / denomination
// money balance_new = balance % denomination
...
printf("%22.4lf\n", SSYMONEY_TO_double(ssytotal));
printf("Toonies %3lld %9.4lf\n", toonies, SSYMONEY_TO_double(balToonies));
printf("Loonies %3lld %9.4lf\n", loonies, SSYMONEY_TO_double(balLoonies));
...
Alternative later
The next version of C may support decimal floating point. Use that for money.
You can use integer types.
int nominals[] = {100, 25, 10, 5, 1, 0};
void getNominals(double money, int *result)
{
unsigned ncents = money * 100.0;
int *nm = nominals;
while(*nm && ncents)
{
*result++ = ncents / *nm;
ncents %= *nm++;
}
}
int main(void)
{
int result[sizeof(nominals) / sizeof(nominals[0])] = {0};
getNominals(4.36, result);
for(size_t index = 0; nominals[index]; index++)
{
printf("%d = %d\n", nominals[index], result[index]);
}
}
https://godbolt.org/z/3KKbfzh4z
Thank you guys for your help! I have learned a lot. When I made this post I should have mentioned that I'm allowed only <stdio.h> library and no functions.
I came up with this solution. Please let me know what do you think.
#include <stdio.h>
int main() {
double total = 365.5700;
int toonies, loonies, quarters, dimes, nickels, pennies;
double balToonies, balLoonies, balQuarters, balDimes, balNickels, balPennines;
// Toonies
toonies = (int)total / 2;
balToonies = (int)(total * 100 + 0.5) % 200 / 100.0;
// Loonies
loonies = (int)balToonies / 1;
balLoonies = (int)(balToonies * 100 + 0.5) % 100 / 100.0;
// Quarters
quarters = (int)(balLoonies * 100) / 25;
balQuarters = (int)(balLoonies * 100 + 0.5) % 25 / 100.0;
// Dimes
dimes = (int)(balQuarters * 100) / 10;
balDimes = (int)(balQuarters * 100 + 0.5) % 10 / 100.0;
// Nickels
nickels = (int)(balDimes * 100) / 5;
balNickels = (int)(balDimes * 100 + 0.5) % 5 / 100.0;
// Pennies
pennies = (int)(balNickels * 100);
balPennines = (int)(balNickels * 100 + 0.5) % 1 / 100.0;
printf("Sales INCLUDING tax\n");
printf("Coin Qty Balance\n");
printf("-------- --- ---------\n");
printf("%22.4lf\n", total);
printf("Toonies %3d %9.4lf\n", toonies, balToonies);
printf("Loonies %3d %9.4lf\n", loonies, balLoonies);
printf("Quarters %3d %9.4lf\n", quarters, balQuarters);
printf("Dimes %3d %9.4lf\n", dimes, balDimes);
printf("Nickels %3d %9.4lf\n", nickels, balNickels);
printf("Pennies %3d %9.4lf\n\n", pennies, balPennines);
return 0;
}
Related
I am not quite sure how to fix the program to make it display the change someone has correctly. I will list the expected outputs and the actual outputs below, as well as the code that I have written thus far. Any help is greatly appreciated, as I am very unsure about how to go about completing this project.
Expected output for input "4.67":
Dollar Bills: 4
Quarters: 2
Dime: 1
Nickel: 1
Pennies: 2
Actual output:
Dollar Bills: 223187040
Cents Leftover
Quarters: 0
Dimes: 0
Nickels: 0
Pennies: 0
#include <stdio.h>
double user_change(double);
void user_cents(int cents);
int main() {
double user_amt, cents;
printf("Hello User!\n\nHow much money would you like change for?\nEnter any amount: $");
scanf("%lf", &user_amt);
user_change(user_amt);
user_cents(cents);
return 0;
}
double user_change (double user_amt)
{
int updated_amt = (int) user_amt;
int hundreds, fifties, tens, fives, dollar_bills;
double cents = user_amt - updated_amt;
hundreds = updated_amt / 100;
updated_amt %= 100;
fifties = updated_amt / 50;
updated_amt %= 50;
tens = updated_amt / 10;
updated_amt %= 10;
fives = updated_amt / 5;
updated_amt %= 5;
dollar_bills = updated_amt / 100;
updated_amt %= 100;
printf("\nDollar Bills: %d\n", dollar_bills);
}
void user_cents(int cents)
{
int balance = cents * 10;
int quarters, dimes, nickels, pennies;
quarters = balance / 25;
balance %= 25;
dimes = balance / 10;
balance %= 10;
nickels = balance / 5;
balance %= 5;
pennies = balance / 1;
balance %= 1;
printf("\nCents Leftover\nQuarters: %d\nDimes: %d\nNickels: %d\nPennies: %d\n", quarters, dimes, nickels, pennies);
}
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 3 years ago.
Well, suppose that a cashier owes a customer some change and in that cashier’s drawer are quarters (25¢), dimes (10¢), nickels (5¢), and pennies (1¢). The problem to be solved is to decide which coins and how many of each to hand to the customer
if some customer is owed 41¢, the biggest first bite that can be taken is 25¢
41 - 25 = 16
another 25¢ bite would be too big
cashier would move on to a bite of size 10¢, leaving him or her with a 6¢ problem
At that point the cashier calls for one 5¢ bite followed by one 1¢ bite
#include <cs50.h>
#include <stdio.h>
int main(void)
{
float f = get_float("Enter Cash: ");
int q;
int d;
int n;
int p;
float quarter = 0.25;
float dimes = 0.10;
float nickels = 0.05;
float pennies = 0.01;
while ( f != 0)
{
if (f >= quarter){
f = f - quarter;
q = q + 1;
} else if (f >= dimes && f < quarter) {
f = f - dimes;
d = d + 1;
} else if (f >= nickels && f < dimes) {
f = f - nickels;
n = n + 1;
} else {
f = f - pennies;
p = p + 1;
}
printf ("Quarter: %d \n Dimes %d \n Nickels %d \n Pennies %d \n", q,
d, n, p);
}
}
$ ./cash
Enter Cash: 6
Quarter: 32768
Dimes -1230737968
Nickels 0
Pennies 4205168
Quarter: 32769
Dimes -1230737968
Nickels 0
Pennies 4205168
Quarter: 32770
Dimes -1230737968
Nickels 0
Pennies 4205168
Quarter: 32771
Dimes -1230737968
Nickels 0
Pennies 4205168
Quarter: 32772
you need to initialize your variables
int q = 0;
int d = 0;
int n = 0;
int p = 0;
otherwise they have unpredictable values
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 4 years ago.
I am declaring the amount as a float. When I multiply the value by 100 and plug it into an "int" variable the value changes to 419... why is this happening?
#include <stdio.h>
#include <cs50.h>
#include <math.h>
float amount;
int cents, coins, quarters, dimes, nickels, pennies, Q, D, N, P;
int main(void){
do
{
amount = get_float("How much we talkin?\n");
}
while (amount < 0);
printf("cents = %.55f\n", amount);
cents = amount * 100;
printf("cents = %i\n", cents);
quarters = cents % 25;
Q = cents / 25;
printf("quarters = %i\n", quarters);
dimes = quarters % 10;
D = quarters / 10;
printf("dimes = %i\n", dimes);
nickels = dimes % 5;
N = dimes / 5;
printf("nickels = %i\n", nickels);
pennies = nickels % 1;
P = nickels / 1;
printf("pennies = %i\n", pennies);
coins = Q+D+N+P;
printf("%i\n", coins);
}
~/workspace/pset1/cash/ $ ./cash
How much we talkin?
4.2
cents = 4.1999998092651367187500000000000000000000000000000000000
cents = 419
quarters = 19
dimes = 9
nickels = 4
pennies = 0
22
... that link helped. Thank you!
Thank you, I resolved this issue by taking the input from the user as a float, multiplying that value by 100, then rounding to the nearest integer. The code below works, not the cleanest solution in the world.
#include <stdio.h>
#include <cs50.h>
#include <math.h>
float amount;
int cents, coins, quarters, dimes, nickels, pennies, Q, D, N, P;
int main(void){
do
{
amount = get_float("How much we talkin?\n");
}
while (amount < 0);
// Print float input to see value is not precise
printf("amount = %.55f\n", amount);
// Multiply amount by 100, then round to nearest
cents = roundf(amount * 100);
printf("cents = %i\n", cents);
// *Quarters*
quarters = cents % 25;
Q = cents / 25;
printf("quarters = %i\n", Q);
// *Dimes*
dimes = quarters % 10;
D = quarters / 10;
printf("dimes = %i\n", D);
// *Nickels*
nickels = dimes % 5;
N = dimes / 5;
printf("nickels = %i\n", N);
// *Pennies*
pennies = nickels % 1;
P = nickels / 1;
printf("pennies = %i\n", P);
// Add up all the coins
coins = Q+D+N+P;
printf("%i\n", coins);
}
~/workspace/pset1/cash/ $ ./cash
How much we talkin?
4.2
amount = 4.1999998092651367187500000000000000000000000000000000000
cents = 420
quarters = 16
dimes = 2
nickels = 0
pennies = 0
18
To understand this issue, you need to understand how floating point numbers are stored in memory, in their binary form.
You also need to understand that C's type conversion TRUNCATES a float when converting to an integer.
The number 4.2 is stored as:
1 x 4
0 x 2
0 x 1
0 x 0.5
0 x 0.25
1 x 0.125
1 x 0.0625
0 x 0.03125
0 x 0.015625
1 x 0.0078125
1 x 0.00390625
etc
Which sums to 4.199 (and eventually approximates to 4.199999 - but NEVER 4.2)
Multiplying by 100 gives you 419.999(etc) - and truncating this gives you 419 not 420.
The solution (as you have found) is to make sure you ROUND rather than TRUNC
This question already has answers here:
Is floating point math broken?
(31 answers)
Closed 5 years ago.
Hi so I'm struggling to figure out what's wrong with my code. I'm really new at this so bear with me. Comments might be a little messy atm.
#include <stdio.h>
int main(void)
{
double cost, gstCost, newCost; // initial cost, cost of gst by itself, new cost after gst
int loonies, quarters, dimes, nickels, pennies; // used for quantity of coins
float loonreq, quartreq, dimereq, nickreq, penreq; // cost required after deduction of the corresponding coin
printf("Please enter the amount to be paid: $");
scanf("%lf", &cost); // scanf allows to input an amount as a double ("%lf")
gstCost = cost * .13 + .005; // .13 for gst and add 0.005 to round up or down
printf("GST: %.2lf\n", gstCost);
newCost = cost + gstCost;
printf("Balance owing: $%.2lf\n", newCost); // original cost + gst cost
loonies = newCost; // loonies will output as integer when cost has decimals
printf("Loonies required: %d", loonies);
if (loonies == 0) // == used to compare equality
loonies = 1; // if loonies = 0, loonreq will be infinite causing code to crash and stop
loonreq = (float)((int)(100 * newCost) % (100 * loonies)) / 100; // casting int and * 100 on float values for modulo since it can only calculate for integer value
printf(", balance owing $%.2f\n", loonreq); // %.2f shows a float with 2 decimal places
quarters = 100 * loonreq / 25; // 100*loonreq allows the code to find how many quarters by dividing by 25
printf("Quarters required: %d", quarters);
if (quarters == 0)
quarters = 1;
quartreq = (float)((int)(100 * loonreq) % (int)(100 * (quarters * .25))) / 100;
printf(", balance owing $%.2f\n", quartreq);
dimes = 100 * quartreq / 10;
printf("Dimes required: %d", dimes);
if (dimes == 0)
dimes = 1;
dimereq = (float)((int)(100 * quartreq) % (int)(100 * (dimes * .10))) / 100;
printf(", balance owing $%.2f\n", dimereq);
nickels = 100 * dimereq / 5;
printf("Nickels required: %d", nickels);
if (nickels == 0)
nickels = 1;
nickreq = (float)((int)(100 * dimereq) % (int)(100 * (nickels * .05))) / 100;
printf(", balance owing $%.2f\n", nickreq);
pennies = 100 * nickreq / 1;
printf("Pennies required: %d", pennies);
if (pennies == 0)
pennies = 1;
penreq = (float)((int)(100 * nickreq) % (int)(100 * (pennies * .01))) / 100;
printf(", balance owing $%.2f\n", penreq);
return 0;
}
When I run this code on Visual Studio, I get the correct outputs for certain inputs like 8.68 but when I submit this file through PuTTY for my professor, it tests it for me and I get an incorrect balance (a penny off) after dimes deducted. When I put in a value like 76.54, I'm a penny off after the deduction of loonies. Inputting a value like 76.76, I get the correct output. I don't exactly know what's happening. My professor looked at my code and said it's because of type changes? and recommended that I use this method instead, example
dimes = (balance / 100) / 0.1;
balance = (int)(balance) % 10;
I'm not sure how to use this method though.
Edit: I need to use the modulus operator and casting for this assignment. gcc is used when I submit on PuTTy.
The rounding logic is not giving the correct answer. Say we have an input 123. The GST should be 15.99. However your code will give 16.00. To fix this try replacing gstCost = cost * .13 + .005; with gstCost = (round(cost * .13 * 100) / 100);
Don't use float/double at all for money. Computers are binary and use base 2 math. Not all decimal values (base 10) can be represented precisely in base 2 floating point, causing rounding errors. Do your math with int (or long long) representing pennies and it will be accurate up to the max value of a 32-bit signed int (millions) or 64-bit signed long long (quadrillions).
(float)((int)(100 * quartreq) % (int)(100 * (dimes * .10))) / 100;
I'm sure that changing types like float to int and vise versa can lose a some data throught the parsing part.
example: you have a double variable set as 1.2 when you parse it to int it become 1 and not 1.2 and it won't become 1.2 when you parse it back to double.
Do your calculations with the float type and if you want to change data type only parse it in the final result.
I am trying to write a program to calculate change, but it doesn't seem to work.
I think that the problem is the owed 1/ paid 1; when I tried to print there values I got nothing (0).
Any help ?
#include <stdio.h>
int main()
{
double owed, paid;
int dollars, quarters, dimes, nickels, cents, remainder, owed1, paid1;
printf("how much did the customer have to pay ?\n");
scanf("%f",&owed);
printf("how much did the customer pay ?\n");
scanf("%f",&paid);
owed1 = owed * 100;
paid1 = paid * 100;
int change = paid1 - owed1;
dollars = change / 100;
remainder = change % 100;
quarters = remainder / 25;
remainder = remainder % 25;
dimes = remainder / 10;
remainder = remainder % 10;
nickels = remainder / 5;
remainder = remainder % 5;
cents = remainder;
printf("%d",dollars);
printf("Dollars:%d, Quarters:%d, Dimes:%d, Nickels:%d, Cents:%d", dollars , quarters , dimes , nickels , cents );
return 0;
}
You're using %f in your scanf, which is the format specifier for a float, but your variables are doubles. You should use %lf instead:
scanf("%lf",&owed);
Same thing for paid. You should be getting warning from your compiler about that.