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

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.

Related

Does anyone know what is the problem in this code? it's not work at all

I wrote this code and it's not working at all
I hope my explaining is good
.
So what I need from the "for" loop is to continue to the last condition I had. and at the end print the counter number
{
//to do math
float quarters = 0.25;
float dimes = 0.10;
float nickels = 0.5;
float pennies = 0.1;
//the number I need to transfer to 0
float n = 0.65;
//the counting number
int count = 0;
for (;;)
{
if (n >= quarters ) // -0.25
{
n = n - quarters;
count += 1;
return n ;
}
else if (n >= dimes) // -0.10
{
n = n - dimes;
count += 1;
return n ;
}
else if (n >= nickels) // 0.5
{
n = n - nickels;
count += 1;
return n ;
}
else if (n >= pennies) // 0.1
{
n = n - pennies;
count += 1;
return n ;
}
else //return the counting number
{
printf("%i",count);
break;
}
}
}
Do not return n, use continue instead - continue will tell your loop to go another round and that is what you want here in order to go through the conditional logic again.
return terminates your function, so your program exits before reaching the final else branch where you would print out the counter.
Also, your pennies are set as 0.1, the same as dimes, and should be set to 0.01, I assume.
EDIT:
Per comment of Weather Vane posted under the question, it might be better to use integers for this problem, due to the misrepresentation of 0.01 in floating point. The SO question he has linked: Why not use Double or Float to represent currency?

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

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.

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.

Why are the conditional statements in the while loop causing the program to pause selectively forever?

I am trying to figure out what the minimum number of coins required to pay back change is by using a "greedy algorithm". The program I have written below is working as expected if the user enters a multiple of only one of the constant integers. However, when it comes to to dealing with more than one coin, the program just pauses forever.
I think that the problem is in my CountGreed function's while loop on the conditional statements. I have tried finding answers but nothing I have come across seems to be giving me insight to guide me to understanding what the matter is with my logic.
I know this is trivial and there is repetition in the loop through the conditional statements which then brings me to the stated question. Multiples of 0.25, 0.10, 0.05 and 0.01 are working well if entered by the user. For example, 1.00, 1.25, 0.20 but not 0.30, 1.13, 0.26, etc.
#include "cs50.h" // Contains declaration for GetFloat()
#include <stdio.h>
#include <math.h>
float PromptChange(void); // Returns customer change in dollars
int ConvertToCents(float); // Returns a conversion from dollars to cents
int CountGreed(int); // Returns the minimum number of coins for which change can be made
int main (void)
{
float Dollars = PromptChange();
int Cents = ConvertToCents(Dollars);
int CoinCount = CountGreed(Cents);
printf("The minimum number of coins required to give back change is %i.\n", CoinCount);
return 0;
}
float PromptChange(void)
{
float Dollars;
do {
printf ("Owed change: $");
Dollars = GetFloat ();
} while (Dollars < 0);
return Dollars;
}
int ConvertToCents(float Dollars)
{
float Cents = Dollars * 100;
int IntCents = (int)roundf(Cents);
return IntCents;
}
int CountGreed(int IntCents)
{
const int Quarter = 25, Dime = 10, Nickel = 5, Penny = 1;
int SubCoinCount = 0;
int CoinCount = 0;
int Remainder = 0;
while (IntCents) {
if (IntCents >= Quarter) {
SubCoinCount = IntCents / Quarter;
CoinCount += SubCoinCount;
Remainder += IntCents % Quarter;
IntCents = Remainder;
} else if (IntCents < Quarter && IntCents >= Dime) {
SubCoinCount = IntCents / Dime;
CoinCount += SubCoinCount;
Remainder += IntCents % Dime;
IntCents = Remainder;
} else if (IntCents < Dime && IntCents >= Nickel) {
SubCoinCount = IntCents / Nickel;
CoinCount += SubCoinCount;
Remainder += IntCents % Nickel;
IntCents = Remainder;
} else if (IntCents < Nickel && IntCents >= Penny) {
SubCoinCount = IntCents / Nickel;
CoinCount += SubCoinCount;
Remainder += IntCents % Dime;
IntCents = Remainder;
}
}
return CoinCount;
}
I pasted the whole main.c file so that the flow of my entire program can be seen clearly though the problem is with the loop. I have tried this on multiple compilers just to make sure that it is my fault.
This:
else if (IntCents < Nickel && IntCents >= Penny) {
SubCoinCount = IntCents / Nickel;
CoinCount += SubCoinCount;
Remainder += IntCents % Dime;
IntCents = Remainder;
}
should be this:
else if (IntCents < Nickel && IntCents >= Penny) {
SubCoinCount = IntCents / Penny; // <--- Change to Penny, or just remove
CoinCount += SubCoinCount;
Remainder += IntCents % Penny; // <--- Change to Penny
IntCents = Remainder;
}
Your four if cases are identical except for the denomination of the coin, which means they're crying out to be put into a separate function. Doing that is a great way to avoid making errors like this in one or some of your cases, because you're only writing it once.
I also suspect:
Remainder += IntCents % Dime;
should be:
Remainder = IntCents % Dime;
otherwise Remainder will increase endlessly, and IntCents will never get to zero. Remainder actually becomes unnecessary, in this case, and you can assign the result directly to IntCents.
But there's a simpler way of doing this entirely. Here's a suggested alternative, for your perusal:
#include <stdio.h>
// This cries out to be its own function
int coin_count(int cents, int denomination, int * remainder)
{
*remainder = cents % denomination;
return cents / denomination;
}
// Better way
int CountGreed(int IntCents)
{
static const int Quarter = 25, Dime = 10, Nickel = 5, Penny = 1;
int CoinCount = 0;
while ( IntCents > 0 ) {
if ( IntCents >= Quarter ) {
CoinCount += coin_count(IntCents, Quarter, &IntCents);
} else if ( IntCents >= Dime ) {
CoinCount += coin_count(IntCents, Dime, &IntCents);
} else if ( IntCents >= Nickel ) {
CoinCount += coin_count(IntCents, Nickel, &IntCents);
} else if ( IntCents >= Penny ) {
CoinCount += coin_count(IntCents, Penny, &IntCents);
}
}
return CoinCount;
}
// Even better way
int CountGreed2(int IntCents)
{
static const int coins[4] = {25, 10, 5, 1};
int CoinCount = 0;
for ( int i = 0; i < 4; ++i ) {
if ( IntCents >= coins[i] ) {
CoinCount += coin_count(IntCents, coins[i], &IntCents);
}
}
return CoinCount;
}
int main(void) {
printf("Coins for $1.25 (should be 5): (%d)\n", CountGreed(125));
printf("Coins for $1.00 (should be 4): (%d)\n", CountGreed(100));
printf("Coins for $0.96 (should be 6): (%d)\n", CountGreed(96));
printf("Coins for $1.25 (should be 5): (%d)\n", CountGreed2(125));
printf("Coins for $1.00 (should be 4): (%d)\n", CountGreed2(100));
printf("Coins for $0.96 (should be 6): (%d)\n", CountGreed2(96));
return 0;
}
which outputs:
paul#local:~/Documents/src/sandbox$ ./coins
Coins for $1.25 (should be 5): (5)
Coins for $1.00 (should be 4): (4)
Coins for $0.96 (should be 6): (6)
Coins for $1.25 (should be 5): (5)
Coins for $1.00 (should be 4): (4)
Coins for $0.96 (should be 6): (6)
paul#local:~/Documents/src/sandbox$
The need for a separate function in CountGreed2() is less obvious, since you're only writing it once anyway, but tastes vary.
#include "cs50.h" // Contains declaration for GetFloat()
#include <stdio.h>
#include <math.h>
float PromptChange(void); // Returns customer change in dollars
int ConvertToCents(float); // Returns a conversion from dollars to cents
int CountGreed(int); // Returns the minimum number of coins for which change can be made
int main (void)
{
float Dollars = PromptChange();
int Cents = ConvertToCents(Dollars);
int CoinCount = CountGreed(Cents);
printf("The minimum number of coins required to give back change is %d.\n",
CoinCount);
return 0;
}
float PromptChange(void)
{
float Dollars;
do {
printf ("Owed change: $");
Dollars = GetFloat ();
} while (Dollars < 0);
return Dollars;
}
// the original function ConvertToCents()
// will usually return an incorrect value
// typically off by 1
// This is because float values often cannot exactly represent
// the desired value
int ConvertToCents(float Dollars)
{
float Cents = Dollars * 100.0f; // note all values should be float
int IntCents = floor(Cents+.5f); // round up to whole penny
return IntCents;
}
int CountGreed(int IntCents)
{
const int Quarter = 25, Dime = 10, Nickel = 5, Penny = 1;
int CoinCount = 0;
int Remainder = IntCents; // get working value
// note following using integer divides
CoinCount = Remainder / Quarter; // max quarters
Remainder = Remainder % Quarter; // update working value
CoinCount += Remainder / Dime; // max dimes
Remainder = Remainder % Dime; // update working value
CoinCount += Remainder / Nickle; // max nickles
Remainder = Remainder % Nickle; // update working value
CoinCount += Remainder; // final pennys
return CoinCount;
}

Resources