Ctpelnar1988 Ctpelnar1988 - 3 months ago 17
C Question

Infinite while loop in C when given value and subtracting until zero

I have just began to learn C. I am writing a program that gives change back to the customer in quarters, nickels, dimes and pennies. For some reason when the

while
loop reaches 0 it does not break.

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

int main(void){
float val;
int quarters = 0;
int dimes = 0;
int nickels = 0;
int pennies = 0;

printf("How much change is due?: \n");

val = GetFloat();

while (val > 0){

if (val >= 0.25){
quarters += 1;
val -= 0.25;
}
else if (val >= 0.1) {
dimes += 1;
val -= 0.1;
}
else if (val >= 0.05){
nickels += 1;
val -= 0.05;
}
else if (val >= 0.01){
pennies += 1;
val -= 0.01;
}

printf("%f \n", val);
}

printf("Quarters: %i\n", quarters);
printf("Dimes: %i\n", dimes);
printf("Nickels: %i\n", nickels);
printf("Pennies: %i\n", pennies);

return 0;
}


Any suggestions on how to handle?

Answer

This is because float can't represent all values 100% correctly. For some input values your program will end up with valbeing greater than zero and less than 0.1. Then you have a deadlock.

Changing your print to:

printf("%0.30f \n", val);

will output:

0.009999995119869709014892578125

on my system.

A better approach could be to do the calculations in int instead. Something like:

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

int main(void){
    float val;
    int intval;
    int quarters = 0;
    int dimes = 0;
    int nickels = 0;
    int pennies = 0;

    printf("How much change is due?: \n");

    val = GetFloat();

    intval = roundf(100 * val);  // Multiply by 100 and convert to int

    // Use intval instead of val for the remaining code
    while (intval > 0){

        if (intval >= 25){     // note: 0.25 --> 100 * 0.25 --> 25 
            quarters += 1;     // similar for all other code below 
            intval -= 25;
        }
        else if (intval >= 10) {
            dimes += 1;
            intval -= 10;
        }
        else if (intval >= 5){
            nickels += 1;
            intval -= 5;
        }
        else if (intval >= 1){
            pennies += 1;
            intval -= 1;
        }

        printf("%d \n", intval );
    }

    printf("Quarters: %i\n", quarters);
    printf("Dimes: %i\n", dimes);
    printf("Nickels: %i\n", nickels);
    printf("Pennies: %i\n", pennies);

    return 0;
}