我正在做cs50x,我的工作遇到了麻烦。我应该创建一种算法,该算法将输出退回硬币所需的最少硬币。例如0.41美元将是4个硬币,一个四分之一(0.25),两个角钱(0.10)和一个美分(0.01)。由于某种原因,该算法无法正常工作(输出的硬币数量不正确),我无法计算原因:

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

int Coins;
float Owed;

int main(void)
{
    printf("How much is owed?\n");
    Owed = GetFloat();
    while (Owed < 0)
    {
        printf("A positive number please");
        Owed = GetFloat();
    }
    if (Owed >= 0.25)
    {
        while (Owed >=0.25)
        {
            Owed = Owed - 0.25;
            Coins++;
        }
    }

     if (Owed >= 0.1)
    {
        while (Owed >=0.1)
        {
            Owed = Owed - 0.1;
            Coins++;
        }

    }

       if (Owed >= 0.05)
    {
        while (Owed >=0.05)
        {
            Owed = Owed - 0.05;
            Coins++;
        }

    }

       if (Owed >= 0.01)
    {
        while (Owed >= 0.01)
        {
            Owed = Owed - 0.01;
            Coins++;
        }

    }
    printf("%d",Coins);
}


当我运行代码并使用0.41作为欠款时,当答案应为4时,我得到了3个硬币:

GreedyNotWorkTerminalPage

最佳答案

您使用的数字(0.1、0.05、0.01)没有精确表示为浮点数,与2/3没有精确表示为4位十进制数的方式相同。 C将改为使用最接近的float值,因此错误非常小,但这足以使您的比较意外失败。

想象一下,如果浮点数是4位数的小数,而您拥有2/3美元的硬币:


开始于欠= 2.0000
欠> = 0.6667,所以欠-= 0.6667。现在欠= 1.3333
1.3333> = 0.6667,所以欠-= 0.6667。现在欠= 0.6666
糟糕!欠= 0.6666,但不是> = 0.6667


您可以通过更改比较值来解决此问题,以允许出现一些舍入错误。不用说>=0.25>=0.1>=0.01,而是使用>=0.245>=0.095>=0.005

不过,通常最好使用一种可以精确表示您要使用的值的类型。代替float美元,使用int美分。

08-24 18:40