-1

I am declaring the amount as a float. When I multiply the value by 100 and plug it into an "int" variable the value changes to 419... why is this happening?

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

float amount;
int cents, coins, quarters, dimes, nickels, pennies, Q, D, N, P;
int main(void){

do
{
    amount = get_float("How much we talkin?\n");
}
while (amount < 0);
        printf("cents = %.55f\n", amount);
cents = amount * 100;
        printf("cents = %i\n", cents);
quarters = cents % 25;
    Q = cents / 25;
        printf("quarters = %i\n", quarters);
dimes = quarters % 10;
    D = quarters / 10;
        printf("dimes = %i\n", dimes);
nickels = dimes % 5;
    N = dimes / 5;
        printf("nickels = %i\n", nickels);
pennies = nickels % 1;
    P = nickels / 1;
        printf("pennies = %i\n", pennies);
coins = Q+D+N+P;

    printf("%i\n", coins);

}

~/workspace/pset1/cash/ $ ./cash
How much we talkin?
4.2
cents = 4.1999998092651367187500000000000000000000000000000000000
cents = 419
quarters = 19
dimes = 9
nickels = 4
pennies = 0
22

... that link helped. Thank you!

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278

2 Answers2

1

Thank you, I resolved this issue by taking the input from the user as a float, multiplying that value by 100, then rounding to the nearest integer. The code below works, not the cleanest solution in the world.

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

float amount;
int cents, coins, quarters, dimes, nickels, pennies, Q, D, N, P;
int main(void){

do
{
    amount = get_float("How much we talkin?\n");
}
while (amount < 0);
    // Print float input to see value is not precise
    printf("amount = %.55f\n", amount);

// Multiply amount by 100, then round to nearest
cents = roundf(amount * 100);
    printf("cents = %i\n", cents);

// *Quarters*
quarters = cents % 25;
    Q = cents / 25;
    printf("quarters = %i\n", Q);

// *Dimes*
dimes = quarters % 10;
    D = quarters / 10;
    printf("dimes = %i\n", D);

// *Nickels*
nickels = dimes % 5;
    N = dimes / 5;
    printf("nickels = %i\n", N);

// *Pennies*
pennies = nickels % 1;
    P = nickels / 1;
    printf("pennies = %i\n", P);

// Add up all the coins
coins = Q+D+N+P;

    printf("%i\n", coins);

}


~/workspace/pset1/cash/ $ ./cash
How much we talkin?
4.2
amount = 4.1999998092651367187500000000000000000000000000000000000
cents = 420
quarters = 16
dimes = 2
nickels = 0
pennies = 0
18
  • Rather than `cents = roundf(amount * 100);`, consider `cents = lrint(amount * 100.0);` `long lrint( double arg )` available since C99, does the rounding and conversion to an integer in one call. Using a `double 100.0` insures no rounding in the product calculation which may occur with `some_float * 100`. – chux - Reinstate Monica Jun 28 '18 at 12:49
0

To understand this issue, you need to understand how floating point numbers are stored in memory, in their binary form.

You also need to understand that C's type conversion TRUNCATES a float when converting to an integer.

The number 4.2 is stored as:

  • 1 x 4
  • 0 x 2
  • 0 x 1
  • 0 x 0.5
  • 0 x 0.25
  • 1 x 0.125
  • 1 x 0.0625
  • 0 x 0.03125
  • 0 x 0.015625
  • 1 x 0.0078125
  • 1 x 0.00390625
  • etc

Which sums to 4.199 (and eventually approximates to 4.199999 - but NEVER 4.2)

Multiplying by 100 gives you 419.999(etc) - and truncating this gives you 419 not 420.

The solution (as you have found) is to make sure you ROUND rather than TRUNC

Andrew
  • 2,046
  • 1
  • 24
  • 37