首页 文章

当给定值并减去零时,无限循环在C中

提问于
浏览
2

我刚刚开始学习C.我正在编写一个程序,以季度,镍币,硬币和便士的形式给客户带来变化 . 出于某种原因,当 while 循环达到0时,它不会中断 .

EDIT: 这个问题与SO上的另一个问题非常相似(Is floating point math broken?) . 我会为那些寻找有关while循环的答案的人保留这个问题,就像我自己一样,他不知道浮点数是否会导致无限循环 .

#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;
}

有关如何处理的任何建议?

2 回答

  • 0

    这是因为 float 无法正确表示100%的所有值 . 对于某些输入值,程序最终将 val 大于零且小于0.1 . 然后你就陷入了僵局 .

    将您的打印更改为:

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

    将输出:

    0.009999995119869709014892578125

    在我的系统上 .

    更好的方法是在 int 中进行计算 . 就像是:

    #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;
    }
    
  • 7

    使用调试器进行检查,您将看到浮点值不准确 . 在这个例子中 . 在分配 val = (float)0.41 后你可以在gdb中看到:

    (gdb) p val
    $2 = 0.409999996
    

    发生无限循环是因为最后val大于0但小于0.01

    最简单的解决方案是打破这种情况 . 当然你可能会失去一分钱:

    while (val >= 0.01){
        ...
    

相关问题