Cs50 pset1-cash expected "18\n", not "22\n" - c

I'm a begginer in C and I'm taking cs50. I'm having trouble with pset1/cash. I have no idea what is wrong with my code. The program first asks the user how much change is owed and then spits out the minimum number of coins with which said change can be made. It works fine with most inputs but when I check it I get expected "18\n", not "22\n" Please, what do I need to change?
#include <stdio.h>
#include <cs50.h>
int main(void)
{
float change;
int cents, cents2, cents3, cents4;
int total = 0;
//Ask for user input and check
do
{
change = get_float("How much change?\n");
}
while (change < 0);
change = (change * 100) / 0.01;
//Multiply the float numbers
if (change < 1)
{
change *= 100;
}
else if (change < 10)
{
change *= 10;
}
//Change to int
cents = change;
//How many quarters
while (cents >= 2500)
{
cents -= 2500;
total++;
}
cents2 = cents;
//How many dimes
while (cents2 >= 1000)
{
cents2 -= 1000;
total++;
}
cents3 = cents2;
//How many nickels
while (cents3 >= 500)
{
cents3 -= 500;
total++;
}
cents4 = cents3;
//How many pennies
while (cents4 >= 100)
{
cents4 -= 100;
total++;
}
printf("%i\n", total);
}
Edit: I have finally found my error. In this line: change = (change * 100) / 0.01; I added 0.01 to it and now it works.
change = (change * 10000) + 0.01;

Use the round function to round up your numbers. In this part of your code, you need to add the round function.
change = (change * 100) / 0.01;
It has to be like this:
cents = round(change * 100);
This will round up the numbers to the nearest wholeIf you have other such problems, you can use a debugger such as debug50, in which you put a breakpoint by clicking in the right of the line number, then in your terminal window(the one where you execute clang) you should type:
~/pset1/cash/ $ debug50 ./cash
Or whatever your program is called. This will open the debugger and inside it you will find all the variables and what they are equal to. Press on the button next to the play button to move one line of code forward.
P.S
There are lots of questions exactly like yours. Just search your problem into the Search... at the top of your screen and I daresay you'll find an answer to your problem.

Related

How to make a coin counter give me the amount of coins I put in

So for this proble, double amount is a randomized number with 2 decimals, like 1.41. My job is to cheack how many coins go into it. so that would be 5 quarters, 1 dime, 1 nickle and 1 penny. so adding all that up would be 8 as the answer.
public static int Test7(double amount)
{
double answer =1;
for (int i =0; i < amount; i++)
{
if (amount >= 0.25)
{
answer = amount / 0.25;
}
else if (amount >= 0.10)
{
answer = amount / 0.10;
}
else if (amount >= 0.05)
{
answer = amount / 0.05;
}
else if (amount >= 0.01)
{
answer = amount - 0.01;
}
}
return (int)answer;
}
This code would output the answer as 5 as i believe the way i set it up does not continue the chain down the list and just gives me the first answer.
I tried to use a while loop and it broke the program.

Greedy calculator in C

I need to create a greedy calculator that accepts only .25, .10, .5 and .1.
I need to print the minimum amount of coins needed to fulfil the change.
This is going on a loop and I can't see what to do to fix it.
I am still learning, go easy on me :)
#include <stdio.h>
#include <cs50.h>
#include <math.h>
int main(void) {
int coins = 0;
int change;
int i;
do {
change = get_float("How much change? ");
}
while (change <= 0); /* condition for acceptance*/
int cents = round(change * 100);
if (cents > 0) { /* run all whiles we get to 1c*/
while ((cents - 25) >= 25) { /* run 25c */
coins += 1;
}
while ((cents - 10) >= 10) { /* run 10c*/
coins += 1;
}
while ((cents - 5) >= 5) { /* run 5c*/
coins += 1;
}
while ((cents - 1) >= 1) { /* run 1c*/
coins += 1;
}
} else {
printf("%d", coins);
}
}
There are multiple problems in your code:
change is defined as an int, so the amount entered by the user is truncated before the computation even starts, producing an incorrect result.
you do not update cents in any of the loops, so you get an infinite loop if any of these conditions is true.
note that the conditions are incorrect: (cents - 25) >= 25 is true if cents is greater or equal to 50.
the test if (cents > 0) is incorrect. You would only print the number of coins if cents <= 0.
the last loop is useless, the number of remaining cents is the number of pennies to count.
Here is a modified version:
#include <stdio.h>
#include <cs50.h>
#include <math.h>
int main(void) {
float change;
do {
change = get_float("How much change? ");
}
while (change <= 0); /* condition for acceptance*/
int cents = round(change * 100); /* avoid rounding issues */
int coins = 0;
while (cents >= 25) { /* count quarters */
cents -= 25;
coins += 1;
}
while (cents >= 10) { /* count dimes */
cents -= 10;
coins += 1;
}
while (cents >= 5) { /* count nickels */
cents -= 5;
coins += 1;
}
count += cents; /* count pennies */
printf("%d\n", coins);
return 0;
}
The cents variable never changes. (cents - 25) indeed returns the value of current cents minus 25, but you don't assign it to cents variable, so one of those 4 while loops will always be true.
There is also another probem: get_float function returns float while change variable is int, if the user were to enter a value less than 1, such as .5, it would be casted to 0 and prompt again and again until the user enters a value greater than 1. Also note you would probably get a wrong answer for any non-integer input.

Greedy algorithms: "expression result unused"

I am trying to do a greedy algorithm for CS50, but for some reason I keep getting errors saying "expression result unused" when trying to divide the total sum of cents by 25, 10, 5, etc. Would someone be able to pinpoint where I am going wrong? Thank you so much in advance.
#include <cs50.h>
#include <stdio.h>
#include <math.h>
int main(void)
{
float Change;
int quarters = 25;
int dimes = 10;
int nickels = 5;
int pennies = 1;
int count = 0;
do
{
Change = get_float("Change: ");
}
while (Change < 0);
int cents = round(Change * 100);
while (cents % 25 >= 25)
{
cents/25;
count = count + 1;
}
while (cents % 10 >= 10)
{
cents/10;
count = count + 1;
}
while (cents % 5 >= 5)
{
cents/5;
count = count + 1;
}
while (cents % 1 >= 1)
{
cents/1;
count = count + 1;
}
printf("%d coins", count);
}
Wrong compare
The following is never true. cents % 25, the remainder after division, is always less than 25.
while (cents % 25 >= 25)
Useless code
The below divides by 25 then discards the quotient. #Some programmer dude
cents/25;
Instead in the 25, 10, 5, 1 places
// while (cents % 25 >= 25)
while (cents >= 25)
// cents/25;
cents -= 25;
More efficient code possible. Hint: while loops not needed.
Good to convert input to integers.
Deeper:
int cents = round(Change * 100); produces a float product from Change * 100, then converts to double in calling round(double). Lastly it converts the results to int as part of the assignment.
Could have used roundf(float) and skip the double conversion.
For learner code this is a good start. Note that Change * 100 can causes a rounding error which would show itself in select cases near a half cent. Suggest round(Change * 100.0)
Perhaps use long lround(double x) to expiate the final conversion from double to an integer.
Note that excessively large input causes overflow and undefined behavior.
Just as the error message is telling you: The value you are calculating cents/n isn't going anywhere. I think you are trying to do cents = cents/n.
Also, yourwhile loops are checking the value of cents but you are incrementing the variable count. So you will never exit the loop.

Learning C, need some assistance with "Greedy" CS50 solution

I am very new to C. I come from a python background. I would like to know where I went wrong with my code.
I am doing the cs50 greedy problem. What is wrong with my code? It works with some numbers but others don't work. I am trying to get an input from the user asking how much change to give back, then calculate the minimum number of coins I can give back using only $.25, $.10, $.05, $.01
#include <cs50.h>
#include <stdio.h>
int main(void)
{
float n;
do
{
n = get_float("How much change is owed?\n");
}
while(n == EOF);
int minimumamountofcoins = 0;
if (n/.25 >=1){
do
{
n -= .25;
minimumamountofcoins++;
}
while (n/.25 >= 1);
}
if (n/.1 >=1){
do
{
n -= .1;
minimumamountofcoins++;
}
while (n/.1 >=1);
}
if(n/.05 >=1){
do
{
n -= .05;
minimumamountofcoins++;
}
while (n/.05 >=1);
}
if (n/.01 >=1){
do
{
n -= .01;
minimumamountofcoins++;
}
while (n/.01 >=1);
}
printf("The minimum amount of coins is %d\n", minimumamountofcoins);
}
New code: (works perfectly except when entering 4.2)
#include <cs50.h>
#include <stdio.h>
int main(void)
{
float n;
do
{
n = get_float("How much change is owed?\n");
}
while(n == EOF);
int cents = (int)(n * 100);
int minimumamountofcoins = 0;
if (cents/25 >= 1){
while (cents/25 >= 1)
{
cents -= 25;
minimumamountofcoins++;
}
}
if (cents/10 >= 1){
while (cents/10 >= 1)
{
cents -= 10;
minimumamountofcoins++;
}
}
if(cents/5 >= 1){
while (cents/5 >= 1)
{
cents -= 5;
minimumamountofcoins++;
}
}
if (cents/1 >= 1){
while (cents/1 >= 1)
{
cents -= 1;
minimumamountofcoins++;
}
}
printf("The minimum amount of coins is %d\n", minimumamountofcoins);
}
Since you did not include test cases, I did my own. Here are some of the cases for which your algorithm does not return the correct answer:
.04, .11, .17, .19, .21, .26, .32, etc.
These cases all fail when calculating the number of pennies (in the final do-while loop), and they all return one less coin then they should. This is because of error with floating-point numbers. With print statements, I discovered that when the division for the final penny was being calculated, the same thing occurred each time:
n/.01 = 0.99999999
This is obviously not intended, as this should be equal to 1, and the final penny should be added to the total. Thus, your code, which works in theory, is broken because of floating-point numbers.
To avoid this, you could do any number of things, such as keeping track of dollars and cents separately as integers, change the condition to be n/.01 >= .9999 instead of n/.01 >= 1, treat the amount of money you are doing the calculations on as an integer number of cents, or any other number of things.
Personally, I prefer that last option, treating the amount of money as an integer number of cents. This is easy to do, as all you have to do to convert from dollars to cents is multiply by 100. Thus, the easiest thing to do is to use this same algorithm, except use integers.
Thus, the code would look something like this:
int main(){
float n;
//code that parses in the amount of money, n now stores that amount
int cents = (int)(n * 100);
int minimumamountofcoins = 0;
if (cents/25 >= 1){
while (cents/25 >= 1)
{
cents -= 25;
minimumamountofcoins++;
}
}
if (cents/10 >= 1){
while (cents/10 >= 1)
{
cents -= 10;
minimumamountofcoins++;
}
}
if(cents/5 >= 1){
while (cents/5 >= 1)
{
cents -= 5;
minimumamountofcoins++;
}
}
if (cents/1 >= 1){
while (cents/1 >= 1)
{
cents -= 1;
minimumamountofcoins++;
}
}
printf("The minimum amount of coins is %d\n", minimumamountofcoins);
}

Integer overflow in greedy coin counting

#include <stdio.h>
#include <cs50.h>
#include <math.h>
int main (void) {
printf ("Enter amount: ");
float amount = GetFloat();
int coins = 0;
while (amount != 0) {
if (fmod(amount, 0.25) == 0) {
amount = amount - 0.25;
coins += 1;
}
else if (fmod(amount, 0.10) == 0) {
amount = amount - 0.10;
coins += 1;
}
else if (fmod(amount, 0.05) == 0) {
amount = amount - 0.05;
coins += 1;
}
else {
amount = amount - 0.01;
coins += 1;
}
}
printf ("Coins : %d\n", coins);
}
I'm trying to implement a small greedy algorithm, in which a user inputs an amount of money ( Ex: 9.25 ) and we output the least amount of coins that it takes for us to exchange it in change( 25 cents, 10 cents, 5 cents and 1 cent only).
This algorithm works with int amounts like 10 or 20 and with amounts that only requires the program to use the 25 cents coins.
If I try an amount like 9.10 or 9.01, I get a runtime error, signed integer overflow. I understand what it means, but I don't understand how can the value of coins go so high all of a sudden.
As Danial Tran said it is better to use int when you do logical operations. Please read Why not use Double or Float to represent currency? Also you can avoid while loop.
#include <stdio.h>
#include <cs50.h>
#include <math.h>
int main (void) {
printf ("Enter amount: ");
//float amount = GetFloat(); //Please refer to chqrlie's comments below.
double amount = 0.0;
scanf("%lf",&amount); //I don't know GetFloat() equivalent for double. So using scanf().
long long int amountInt = (long long int) (amount * 100.0);
int coins = 0;
if (25 <= amountInt) {
coins += (amountInt/25);
amountInt = amountInt % 25;
}
if (10 <= amountInt) {
coins += (amountInt/10);
amountInt = amountInt % 10;
}
if (5 <= amountInt) {
coins += (amountInt/5);
amountInt = amountInt % 5;
}
if (1 <= amountInt) {
coins += amountInt;
}
printf ("Coins : %d\n", coins);
}
It seems that no one has answered the particular question
If i try an amount like 9.10 or 9.01, i get a runtime error,signed integer overflow, i understand what it means, but i don't understand how can the value of coins go so high all of a sudden.
so for the sake of completeness, partially as an exercise:
You can find the reason using a debugger. I copied your code and found that it runs for very long. Interrupting it a moment after start revealed that the code freezes repeating this check:
if (fmod(amount, 0.25) == 0) {
amount = amount - 0.25;
coins += 1;
}
At the moment of the interruption amount was about minus 1.2 million and coins almost 5 million. This clearly shows one thing you failed to check: negativity. It can happen easily with floats that you miss the exact zero, as the others have correctly reasoned, no need to repeat that. But if that happens, your program should get worried the moment amount gets negative. Otherwise, under the right conditions, it may as well keep subtracting its way towards negative infinity, and yes, integer overflow will happen in coins.
This is because the computer represent the decimals in binary (power of 2)
For 0.25, the computer can represent it properly in binary. This is because we can obtain 0.25 exactly using power of 2's.
However for 0.10 ( or other denominations mentioned ), they cannot be expressed exactly in powers of 2.
Suppose you try to obtain 0.1 using power of 2's , you won't be able to obtain it exactly. You can just go near it.
0.1 = 0.0625 ( 2^4 ) + 0.03125 ( 2^5 ) + 0.00390625 ( 2^-8) +...
You will approach 0.1 , but you'll never reach 0.1 exactly.
Float, double everyone has a fixed number of bits to represent a decimal. So it will keep only those many bits, whose sum would be slightly less than 0.1
If you want to follow the same approach, you can have 2 possible solutions :-
Use (amount > 0) instead of (amount != 0), or
Use currencies which can be expressed easily in powers of 2 e.g. 0.25, 0.125 , 0.375 , 0.06125.
Your algorithm is not correct:
For example with 30 cents you can exchange to: 25+5 (2 coins) with your algorithm it would be 10+10+10 (3 coins). So greedy means why it's greater than 25 cents then exchange to 25 cents first.
while (amount != 0) {
if (amount >= 0.25) {
amount = amount - 0.25;
coins += 1;
}
else if (amount >= 0.10) {
amount = amount - 0.10;
coins += 1;
}
else if (amount >= 0.05) {
amount = amount - 0.05;
coins += 1;
}
else {
amount = amount - 0.01;
coins += 1;
}
}
If you want to do that way.
Better way:
int coinTypes[] = {0.25, 0.1, 0.05, 0.01};
for (int i = 0; i < 4; i++) {
coins += floor(amount / coinTypes[i];
amount -= coins * coinsTypes[i];
}
The main problem with your algorithm is invalid usage of fmod function. According to definition the result of fmod(num, denom) is
fmod = num - floor(num/denom) * denom
where floor(num/denom) is integer.
Thus, fmod(9.10, 0.25) == 0.1, fmod(9.10, 0.10) == 0.1.
In addition, the manipulation with floating point number rarely gives exact results. so amount is never 0.
You cannot compute this with the float type. Amounts that are not exact multiples of 0.25 cannot be represented exactly in either the float or the double type.
You can fix this problem by computing an exact number of cents and dispatch it using integer arithmetics:
#include <stdio.h>
#include <math.h>
void print_coins(int coins, const char *singular, const char *plural) {
if (coins > 0)
printf(" %d %s", coins, coins > 1 ? plural : singular);
}
int main(void) {
for (;;) {
double amount;
int amountInt, coins, quarters, dimes, nickels, pennies;
printf("Enter amount: ");
if (scanf("%lf", &amount) != 1 || amount <= 0)
break;
amountInt = (int)(amount * 100.0 + 0.5);
quarters = amountInt / 25;
amountInt %= 25;
dimes = amountInt / 10;
amountInt %= 10;
nickels = amountInt / 5;
amountInt %= 5;
pennies = amountInt;
amountInt = 0;
coins = quarters + dimes + nickels + pennies;
printf("coins returned: %d:", coins);
print_coins(quarters, "quarter", "quarters");
print_coins(dimes, "dime", "dimes");
print_coins(nickels, "nickel", "nickels");
print_coins(pennies, "penny", "pennies");
printf("\n");
}
return 0;
}
Notes:
Using float without the + 0.5, the change is incorrect for as little as 100.10: one penny short.
Using float, the change is incorrect for 1000000.10: 3 extra pennies.
To handle amounts above 20 million dollars, you need a larger integral type such as long long int. With that, you can handle amounts exceeding the US national debt.

Resources