Small bug in my short C code. Why? - c

I can't figure out why this works for 90% of the inputs, but not the others. It is meant to tell you how many coins you would get back in change. Most test amounts work fine, but if you enter 4.20 (or $4.20), it returns 23 coins... it should be 18 coins (16 quarters and 2 nickels). Where is the bug? Here is my code:
#include <stdio.h>
#include <cs50.h>
int main(void){
float change = 0.00;
printf("How much change is owed? ");
change = GetFloat();
float quarters = change/.25;
change-= (int)quarters*.25;
float dimes = change/.10;
change-= (int)dimes*.10;
float nickels = change/.05;
change-= (int)nickels*.05;
float pennies = (change+.005)/.01;
change-=(int)pennies*.01;
int total = (int)quarters+(int)dimes+(int)nickels+(int)pennies;
printf("%d\n", total);
return 0;
}

The closest float value to 4.20 is slightly smaller than that (4.19999980926513671875, for the usual 32-bit IEEE754 floats). So after you subtracted the $4 from the 16 quarters, you have an amount left that is slightly smaller than 0.2. Dividing that by 0.1 results in a value slightly smaller than 2, so your nickels value is 1. The same happens then after you subtract your nickel, the value is slightly smaller than 0.1, dividing by 0.05 results in a quotient slightly smaller than 2.
You should use integers only for such a computation, calculating in cents.

Throw out the floating-point calculations. this is all based on hundredths at best, so just use integer division/modulo. Never rely on perfect accuracy in floating point numbers.
#include <stdio.h>
#include <cs50.h>
int main(void){
float fchange = 0.00;
int change = 0;
printf("How much change is owed? ");
fchange = GetFloat();
change = (int)roundf(fchange*100.0);
int quarters = change/25;
change = change % 25;
int dimes = change/10;
change = change % 10;
int nickels = change/5;
change = change % 5;
printf("%d quarters, %d dimes, %d nickels, %d pennies\n", quarters, dimes, nickels, change);
return 0;
}

The other answers have it mostly covered: you should be working with fixed point here, not floating point. Be careful to round properly when going from the floating point input to your fixed point representation, though. Here is a short version I hacked up, which should work for all positive inputs:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char ** argv)
{
float change = atof(argv[1]);
int work = (int)(100*change+0.5);
int quarters, dimes, nickels, pennies;
quarters = work/25; work %= 25;
dimes = work/10; work %= 10;
nickels = work/5; work %= 5;
pennies = work;
printf("%.2f dollars = %d quarters, %d dimes, %d nickels and %d pennies: %d coins total\n",
change, quarters, dimes, nickels, pennies, quarters+dimes+nickels+pennies);
return 0;
}
For example:
./change 4.20
4.20 dollars = 16 quarters, 2 dimes, 0 nickels and 0 pennies: 18 coins total

Related

why does my program not accept subtractions?

So I'm trying to make a code for one of my classes, and for some reason when I try to compile it, it simply won't accept the subtraction sections. Does anyone know what's going on?
Here's the code:
#include <stdio.h>
#include <cs50.h>
#include <math.h>
int main(void) {
float value;
do {
value = get_float("enter value: ");
} while (value >= 0);
value * 100;
int quarter = 25;
int dime = 10;
int nickel = 5;
int penny = 1;
if (value >= quarter) {
while (value >= quarter) {
quarter - value;
}
int quarters = 0;
quarters++;
} else {
while (value >= dime) {
dime - value;
}
int dimes = 0;
dimes++;
} else {
while (value >= nickel) {
nickel - value;
}
int nickels = 0;
nickels++;
} else {
while (value >= penny) {
penny - value;
}
int pennies = 0;
pennies++;
}
printf ("%i pennies, %i nickels, %i dimes, %i quarters\n", pennies, nickels, dimes, quarters);
}
and whenever I try to compile it, it says cash.c:25:20: error: expression result unused [-Werror,-Wunused-value] quarter - value; or any of the other math expressions. I haven't been able to compile it so, if this doesn't work, I would like a heads up. thanks, guys.
There are multiple issues in you code:
the do / while loop continues as long as the entered value is >= 0. This is the exact opposite of what you want. You should continue if the value is negative.
the statements value * 100; and dime - value;... do not have any side effects, as diagnosed by the compiler. You should write value *= 100; or value = value * 100; etc.
multiplying the float value by 100 might not produce an integer because of the limited precision of the floating type and its inability to represent multiples of 0.01 exactly. You should round the value to the nearest integer with value = round(value * 100);
the series of else clauses prevent proper computation of the change to give. As coded, you can only give one kind of coin, and only one of that.
the variables quarters, dimes, nickels and pennies are defined with a local scope that ends before the final printf statement, so they are undefined there and the compiler produces an error.
You can compute the number of quarters with int quarters = floor(value / 25); etc.
Here is a modified version:
#include <cs50.h>
#include <math.h>
#include <stdio.h>
int main(void) {
float value;
do {
value = get_float("enter value: ");
} while (value < 0);
value = round(value * 100);
int quarters = floor(value / 25);
value -= 25 * quarters;
int dimes = floor(value / 10);
value -= 10 * dimes;
int nickels = floor(value / 5);
value -= 5 * nickels;
int pennies = value;
printf ("%i pennies, %i nickels, %i dimes, %i quarters\n", pennies, nickels, dimes, quarters);
return 0;
}
Using integer arithmetic to split value into coins allows for simpler code, using the modulo operator %:
#include <cs50.h>
#include <math.h>
#include <stdio.h>
int main(void) {
float value;
do {
value = get_float("enter value: ");
} while (value < 0);
int cents = round(value * 100);
int quarters = cents / 25; cents %= 25;
int dimes = cents / 10; cents %= 10;
int nickels = cents / 5; cents %= 5;
int pennies = cents;
printf ("%i pennies, %i nickels, %i dimes, %i quarters\n", pennies, nickels, dimes, quarters);
return 0;
}

C Unhandled exception 0xC0000094: Integer division by zero

I have been given this error for two days straight, and I have worked on it for about three hours, altogether. When I run it, it will tell me how many $10 bills I need but just stops at the $5 line and gives me this exception every time.
#define _CRT_SECURE_NO_WARNINGS 'code'
#include <stdio.h>]
#include <stdlib.h>
#include "math.h"
int main()
{
int ten = 10;
int five = 5;
int one = 1;
float quarter = .25;
float dime = .10;
float nickel = .05;
float penny = .01;
double money=0;
printf("Please enter a monetary amount:");
scanf_s("%lf", &money);//scanning the entry in, and & is allowing it to be entered
//money is the input number
printf("You entered: %lf \n", money);//creates too many zeroes but for now move on
ten = money / ten;//dividing the change = 10, and then
money = (int) money % ten;//this determines how many tens there are in the mix
//casted it because it only needs to be an integer not a double
printf("$10 : %d \n", ten);//printing an integer of how many tens are needed to make up money
five = money / five;//dividing the change = 10, and then
money = (int) money % five;//this determines how many tens there are in the mix
//casted it because it only needs to be an integer not a double
printf("$5 : %d \n", five);
//first problemm I had was putting in const, and that gave me a bajillion errors
return(EXIT_SUCCESS);
}
The error that you have mentioned will be shown if you divide a number by zero.just like hanie mentioned in her answer but in your case i don't see a line were you are dividing a number by zero but you have some lines were you overwrite the ten and five variables using modulo operator i guess it might be throwing the error.
I am posting a modified version of your code. Hope it helps you.
#define _CRT_SECURE_NO_WARNINGS 'code'
#include <stdio.h>
#include <stdlib.h>
#include "math.h"
int main()
{
int tens = 0;
int fives = 0;
double money=0;
printf("Please enter a monetary amount:");
scanf("%lf", &money);
printf("You entered: %lf \n", money);
tens = money / 10;
printf("$10 : %d \n", tens);
money = money - tens * 10;
fives = money / 5;
printf("$5 : %d \n", fives);
money = money - fives * 5;
return(EXIT_SUCCESS);
}
Sample Input and Output
Please enter a monetary amount:125
You entered: 125.000000
$10 : 12
$5 : 1
Please enter a monetary amount:123
$10 : 12
$5 : 0
Note that most implementations of floating point math will follow a standard (e.g. IEEE 754), in which case operations like divide-by-zero will have consistent results and the C standard says the operation is undefined.
before doing division you need to do something like this:
if(denominator != 0)
a = a / denominator;
or
if(denominator != 0)
a = a % denominator;

How can I make my C program return change in dollars, quarters, dimes, nickels and pennies?

Code is :
int main()
{
displayOwe(getOwe(), customerpaid());
displayChange(dollars, quarters, dimes, nickels, pennies);
return 0;
}
float getOwe()
{
float owed;
printf("\nHow much does the customer owe? ");
scanf("%f" ,&owed );
return owed;
}
float customerpaid()
{
float paid;
printf("\nHow much did the customer pay? ");
scanf("%f" ,&paid );
return paid;
}
float calculateTotal (float paid, float owed)
{
float answer;
answer = paid - owed;
return answer;
}
float displayOwe(float owed , float paid)
{
printf("\nCustomer owes $%0.2f and paid $%0.2f.", owed, paid);
}
int displayChange(int dollars, int quarters, int dimes, int nickels, int pennies)
{
dollars= ;
quarters=
dimes=
nickels=
pennies=
printf("\n\nCashier should refund %d dollars, %d quarters, %d dimes, %d nickels, and %d pennies.", dollars, quarters, dimes, nickels, pennies);
}
I have to create a C program to calculate change that shows how much the customer owes and how much the customer paid. I did that part and it is working flawlessly but I do not know how to make the program to show how many dollars, quarters, dimes, nickels and pennies the cashier needs to return to the customer. Any help would be appreciated.
displayChange needs two extra arguments - float owed, float paid. The other parameters should be references "&" since they are output parameters.
Inside displayChange I would convert the float to ints:
int iOwed = owed * 100;
int iPaid = paid * 100;
Now a penny is 1, not 0.01 and a dollar is 100, not 1;
Once you have them as ints, start by getting the change:
int change = iPaid - iOwed;
Then get how many of each are owed by going from largest to smallest monetary unit - first dividing, then getting the remainder.
dollars = change / 100;
Use the modulus operator to get the remainder:
remainder = change % 100;
Then continue to calculate the remaining values by using 25, 10, 5 and 1 for quarters, dimes, nickels and pennies.
quarters = remainder / 25;
remainder = remainder % 25;

print all the amounts that can be paid using only n coins

I have a homework problem where the user inputs a number of coins N. The program is supposed to find all the amounts you can make if those coins could be made up of any combination of pennies, nickles, dimes, and quarters.
I had read other posts where they recommend so much to us dynamic programming, so I used DP in my program for the solution below:
#include <stdio.h>
#include <stdlib.h>
// q(quater), d (dime), n(nickle), p(penny).
int find_coin(int *q, int *d, int *n, int *p, int k)
{
int count = 0;
*q = k / 25;
count += *q;
k = k % 25;
*d = k / 10;
count += *d;
k = k % 10;
*n = k / 5;
count += *n;
k = k % 5;
*p = k;
count += *p;
return count;
}
int main() {
int q,d,n,p;
int k = 0;
int i = 0;
int counts = 0;
puts("\nEnter a number of coins: ");
scanf("%d", &k);
find_coin(&q, &d, &n, &p, k);
printf("%3d cents:\t", k);
printf("total of pennies: %d ",p);
printf("total of nickles: %d ",n);
printf("total of Dimes: %d ",d);
printf("total of quaters: %d \n",q);
getchar();
}
My output is:
Enter a number of coins:
5
5 cents: total of pennies: 0 total of nickles: 1 total of Dimes: 0 total of quaters: 0
But my professor now asks me for this output:
Enter the number of coins
2
2 cents: 0 quarters 0 dimes 0 nickels 2 pennies
6 cents: 0 quarters 0 dimes 1 nickels 1 pennies
11 cents: 0 quarters 1 dimes 0 nickels 1 pennies
15 cents: 0 quarters 1 dimes 1 nickels 0 pennies
20 cents: 0 quarters 2 dimes 0 nickels 0 pennies
26 cents: 1 quarters 0 dimes 0 nickels 1 pennies
30 cents: 1 quarters 0 dimes 1 nickels 0 pennies
35 cents: 1 quarters 1 dimes 0 nickels 0 pennies
50 cents: 2 quarters 0 dimes 0 nickels 0 pennies
I tried my solution using a loop, but my loop is incorrect. I did something wrong in the code where the loop is just overloading:
for(i = 1; i > counts; i++) {
printf("%3d cents:\t", k);
printf("total of pennies: %d ",p);
printf("total of nickles: %d ",n);
printf("total of Dimes: %d ",d);
printf("total of quaters: %d \n",q);
k++;
}
You've gotten this backwards, and probably became confused by reading solutions to problems whose only similarity was dealing with coins. Look at what this does:
int find_coin(int *q, int *d, int *n, int *p, int k)
That routine takes in an amount k which is value in cents, and gives back a breakdown of the fewest number of coins that could achieve that amount. Then it returns the count of coins. So if you gave it 26 cents as k it would poke 1 into *q, leave *d and *n at zero, and give you *p as 1. One penny and one quarter makes 26 cents--with a return value indicating two total coins. It wouldn't give you *p as 26 to make 26 cents.
(I'll point out that this has nothing to do with the concept whose somewhat-misleading name is "dynamic programming".)
So if the goal of the program was to take in a total currency value and then print out the fewest coins that make it up, your program would be correct. Imagine if the prompt said:
Enter a number of cents:
Then if you input 5 as with your case, the "optimal" answer is a single coin of one nickel. That's what you got. A correct answer to a problem you weren't assigned.
The real problem is about combinations. If I could have two coins and they could be any from the set...I'd want those to be two quarters for a maximum of 50 cents. But the question is what are all the possibilities, without counting possibilities twice. So you only need to mention two pennies once to make 2 cents.
Look at what your prompt actually says:
Enter a number of coins:
A good lesson here is that you should line up your variable names with things in the problem statement. Both the problem statement (and your question title) talk about "n" coins. So why not call your variable either n or coins? When you name things meaningfully mistakes will jump off the page, as in the mismatch that would have been here between cents and coins:
printf("%3d cents:\t", coins);
Adding some haphazard loops onto this isn't going to get you to the right answer. So it's time to go back to the drawing board. You'll be needing essentially the opposite of find_coin...something that takes a number of quarters, dimes, nickels, and pennies and gives you back the amount of money that represents. And some loops and some research on how to produce combinations.
(Note: When I mention that haphazard loops won't get you the answer, I mean it really can't. One might think that if you were asked to do 5 coins you could say the maximum amount of money in cents would be 5 times 25 for five quarters...with the minimum as 5 times 1 for five pennies. Then count from 5 to 125 and print out all the cent tallies where find_coins returned five coins. But can you see why that can't work? find_coins won't find the five pennies case because it is "inefficient", it can only see that as one nickel. But you're asked to find all combinations of the 5 coins, so that's a combination that needs to be found and output.)

Getting crazy large numbers, possibly due to improper manipulation of doubles and ints (C language)

I'm writing a program for my CS239 class in C that asks for cost of something, amount paid, calculates tax, and then determines what type of change to return and optimal coins to return.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
void coinage(int c, int q, int d, int n, int p); //change calculation function
int main(void)
{
double price, tax, paid, due, t_back; //used double instead of int for decimal purpose
int c, b, q, d, n, p; //change, bills, quarters, dimes, nickels, pennies
printf("\nProgram Author: PuppyBreath\n");
printf("\nEnter price in dollars: $");
scanf("%lf", &price);
tax = 1.06;
due = price*tax;
printf("Sales tax in Kentucky is 6%, therefore the amount due is $%.2f. \n", due);
printf("Enter amount paid: \n");
scanf("%lf", &paid);
paid = paid*100+0.5;
due = due*100;
c = paid-due;
b = c/100;
t_back = (paid-due)/100-0.01; //used a double rather than an int for increased precision
coinage(c, q, d, n, p); //calls coinage function
printf("Change back:\n");
printf("Total: $%.2f\n", t_back);
if(t_back >= 1)
printf("Ones: %d\n", b);
else
printf("No bills\n");
if(q >= 1)
printf("Quarters: %d\n", q);
else
printf("NO QUARTERS FOR YOU!\n");
if(d >= 1)
printf("Dimes: %d\n", d);
else
printf("NO DIMES FOR YOU!\n");
if(n >= 1)
printf("Nickels: %d\n", n);
else
printf("NO NICKELS FOR YOU!\n");
if(p >= 1)
printf("Pennies: %d\n", p);
else
printf("NO PENNIES FOR YOU!\n");
return 0;
}
void coinage(int change, int quarters, int dimes, int nickels, int pennies)
{
int t_change, t_quarters, t_dimes, t_nickels, t_pennies;
t_change = change%100; //use mod to carry remainders and dividing to find number of each coin
t_quarters = t_change/25.00;
t_change = t_change%25;
t_dimes = t_change/10.00;
t_change = t_change%10;
t_nickels = t_change/5.00;
t_change = t_change%5;
t_pennies = t_change+0.5;
quarters = t_quarters;
dimes = t_dimes;
nickels = t_nickels;
pennies = t_pennies;
}
This is my code, and after I compile it this is what happens: (the '8' and '10' are my inputs)
./a.out
Program Author: PuppyBreath
Enter price in dollars: $8
Sales tax in Kentucky is 6%, therefore the amount due is $8.48.
Enter amount paid:
10
Change back:
Total: $1.51
Ones: 1
NO QUARTERS FOR YOU!
NO DIMES FOR YOU!
Nickels: 4195472
NO PENNIES FOR YOU!
As you know, if your change is $1.51 (supposed to be $1.52 but thats another slightly smaller fish) then you definitely don't need 4,195,472 nickels. Why is this happening? Thanks in advance! I'm not extremely experienced in this, I'm only 3 weeks into any C programming, be gentle!
void coinage(int change, int quarters, int dimes, int nickels, int pennies)
Remember that in C, all arguments are passed by value, thus anything you modify in this function, aren't modified in the out world.
Change it to take pointers to simulate pass-by-reference, the signature should look like this, the body should be modified accordingly.
void coinage(int change, int *quarters, int *dimes, int *nickels, *int pennies)
The core problem here is that the coinage function is designed to return multiple values but the writer has not yet learned good ways of doing so.
One alternative is to redesign the interface so that the coinage function only returns one value, but gets called several times. One could make it take three parameters, the amount of change, the denomination of the current coin, and the denomination of smallest coin with higher value than current. It would return a simple int representing the count for the current coin. The existing coinage function effectively contains this as a block of code that is repeated with only changes in the numbers, not what it is doing.
In the main function variables such as q would be replaced by the expression coins(c, 25, 100), meaning the number of 25 unit coins for change amount c given existence of 100 unit coins or bills.

Resources