-1

As a part of the CS50 course we're tasked to create a program (in C) that calculates the least amount of coins ($0.25, $0.10, $0.05 and $0.01) from a value submitted by the user.

My idea was to take the input value and multiply by 100 and use integers since the only value of interest is the number of coins and not the monetary value, hence I don't have to tinker with any decimals.

The code is:

#include <cs50.h>
#include <stdio.h>
#include <math.h>

int main(void)
{
    //If it's NOT a positive number, do this.
    float n;
    do
    {
        n = get_float("Change owed: \n");
    }
    while (n <= 0);

    //Multiplying change owed with 100 to avoid having to deal with decimals.
    int cash = n * 100;

    //Calculating the number of quarters ($0.25).
    int quarters = cash / 25;                           //How many full quarters per cash.
    int quarters_rem = cash % 25;                       //The remainder after full amout of quarters in cash.
    printf("Number of quarters: %i\n", quarters);       //Test how many quarters.
    printf("Remainder: %i\n", quarters_rem);            //Test how much remainder.

    //Calculating the number of dimes ($0.10).
    int dimes = quarters_rem / 10;                      //How many full dimes from the remainder when all quarters are deducted.
    int dimes_rem = round(quarters_rem % 10);           //The remainder after full amount of dimes in quarters_rem.
    printf("Number of dimes: %i\n", dimes);             //Test how many dimes.
    printf("Remainder: %i\n", dimes_rem);               //Test how much remainder.

    //Calculating the number of nickels ($0.05).
    int nickels = dimes_rem / 5;                        //How many full nickels from the remainder when all dimes are deducted.
    int nickels_rem = round(dimes_rem % 5);             //The remainder after full amount of nickels in dimes_rem.
    printf("Number of nickels: %i\n", nickels);         //Test how many nickels.
    printf("Remainder: %i\n", nickels_rem);             //Test how much remainder.

    //Calculating the number of cents ($0.01).
    int cents = nickels_rem;                            //How many full cents from the remainder when all nickels are deducted.
    printf("Number of cents: %i\n", cents);             //Test how many nickels.

    //Prints the least number of coins to be returned.
    int coins = quarters + dimes + nickels + cents;
    printf("%i\n", coins);
}

The thing is that when I run the code and enter 2.2, 6.2 or 8.2, the output gives me a remainder of 20 after calculating the quarters. 2.2 x 100 = 220 -> 25 x 8 = 200 which gives a remainder of 20, as expected. This is true for 2.2, 6.2, 8.2, 10.2, 12.2, 14.2 and so on.

However, this is not! true if I enter 4.2! If I enter 4.2 I expect: 4.2 x 100 = 420 -> 25 x 16 = 400 which ought to give me a remainder of 20, but instead I get a remainder of 19? I don't understand why the remainder is 19 in this instance but 20 in the others?

MikeCAT
  • 73,922
  • 11
  • 45
  • 70

1 Answers1

0

Typical implementation of floating-point stores numbers in binary format, so it cannot precisely store some of decimal numbers.

With this program

#include <stdio.h>

int main(void) {
    float x = 4.2;
    float y = x * 100;
    printf("%.10f\n", y);
    return 0;
}

I got output:

419.9999694824

This shows that 4.2f * 100 became slightly smaller than 420 and converting that to int will result in 419 instead of 420.

To avoid this, you should add smaller value before converting float to int in this case.

int cash = n * 100 + 0.1;
MikeCAT
  • 73,922
  • 11
  • 45
  • 70