-1

I am doing the cs50 problem set "Greedy". Basically asking the user for how much change is owed and then outputting the minimum amount of coins that can equal the inputed amount. It works perfectly, except when I input 4.2 it outputs 22 when it should output 18.

#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);
}
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
R_C
  • 333
  • 2
  • 6
  • 17

2 Answers2

3

It looks like this is an issue with the conversion from float to int. When you try to convert from dollars to cents, you do so with this line of code:

int cents = (int)(n * 100);

However, this line of code, for $4.20, is returning a cent value of 419. This is a problem with rounding and floats, as 4.2 * 100 is returning 419.99999999 instead of 420.0000000, and integer casting truncates instead of rounding. This problem also occurs with $4.18, and probably other values as well.

To prevent this, add 0.5 before the cast, like so:

int cents = (int)(n * 100 + 0.5);

This will ensure that the rounding takes place in the proper direction, as you are never off by more that a trivial float error.

Using the math.h library, you could also use the roundf() function, which will work in the case of negative numbers, just in case.

int cents = (int)(roundf(n*100));
Lavaman65
  • 863
  • 1
  • 12
  • 22
  • 3
    `(int)(n * 100 + 0.5)` likely will meet basic needs but fails under various conditions including negative, large numbers and others. C has about a dozen rounding functions in ``. Use the best tool in the shed. – chux - Reinstate Monica Aug 17 '17 at 20:34
  • 1
    Fair enough. Since the asker is using dollars, I assumed that they could never be negative, but I'll edit the post to include a better rounding method. – Lavaman65 Aug 17 '17 at 20:35
  • Minor: " integer casting rounds down" --> "integer casting truncates the fraction" This differs, again, with - numbers. – chux - Reinstate Monica Aug 17 '17 at 20:37
  • Also true, will fix as well – Lavaman65 Aug 17 '17 at 20:39
  • 1
    Some numerical trivia for UnknowableIneffable: Consider the difference between `roundf(n*100)` and `round(n*100.0)`. With values near +/-x.xx5, the first can round the wrong way due to inexactness of `some_float_n*some_int_100` where `n*100.0` will compute as `double` and the typical extra precision provides correct results. – chux - Reinstate Monica Aug 17 '17 at 20:46
  • I was not aware of that at all! Thanks for the info, although I won't change the post, as it's not necessary to in this case. – Lavaman65 Aug 17 '17 at 20:49
0

Use the round function to round up your numbers. In this part of your code, you need to add the round function.

int cents = (int)(n * 100);

It has to be like this:

cents = round(n * 100);

If 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.

Lost in code
  • 313
  • 1
  • 4
  • 17