C while循环棘手异常

时间:2017-04-05 10:07:19

标签: c while-loop

我是初学者,这是我写的代码的一部分(简化版):

1.提示用户输入一个数字(浮动金额),假设用户只会输入0.05的倍数;

2.计算该金额中的(int)镍币数量。

int main(void)
{
    float amount = 0;
    printf("$ ");
    amount = get_float();

    int n = 0;
    while ((amount - 0.05) >= 0)
    {
        amount -= 0.05;
        n ++;
    } 
    printf("%i nickels\n", n);

}

适用于任何数量< = 0.3或> = 1.2(因此$ 2有40个镍币,$ 0.30有6个镍币);

但是,对于0.35和1.15之间的任何金额,镍少一个镍(因此0.35美元有6个镍币,1美元有19个镍币)

我一步一步打印,结果发现,对于介于0.35和1.15之间的任何数量,程序停在最后的0.050000,而不是回到循环并最后一次循环。

出了什么问题?请帮忙......非常感谢您的时间!

3 个答案:

答案 0 :(得分:4)

你正在遇到浮点舍入。

浮点数永远不准确,请尝试计算

printf("one third 'ish' = %6.20lf\n", (double) 1.0/ (double) 3.0);

看看答案,这不太准确。 :)

您最好的选择是接受输入,将其转换为整数(即​​美分)乘以100,使用round()删除任何小数并分配给long。

    #include <math.h> // to get the round() function
.
.
.
    long amountInCents = round(amount * 100);

然后,将您的代码更改为5美分,而不是0.05美元,并减少5美分,而不是0.05美元

这样,你摆脱了所有“四舍五入”的问题。

编辑:cmaster向我展示使用floor()不起作用,使用$ 0.57作为输入,当使用'double'变量(不是浮点数)时,$ 0.57转换为(long)56!他提供了代码,我简直不敢相信自己的眼睛!

答案 1 :(得分:0)

由于潜在的推理是正确的,因此严格意义上的代码中没有错误;但请注意,pool-2-thread-1, TASK-NO 2 pool-2-thread-2, TASK-NO 1 pool-2-thread-3, TASK-NO 3 Execution of Task No 2 completed Execution of Task No 1 completed Execution of Task No 3 completed All the tasks are executed 数据类型无法准确表示值0.35float也是如此;作为划分(基本上是问题中代码的语义)是通过重复减法实现的,由无法准确表示所需值引起的误差累积。结果是减法的数量与分析预期的结果不同,因为终止条件太快达到。 0.05数据类型不适用于财务计算,即使在如此非常小的日常示例中也是如此。

这太糟糕了,但实际上是这样。

答案 2 :(得分:-1)

我找到了解决办法。这是有效的

enter code here

while ((amount - 0.0499) >= 0)
{
    amount -= 0.05;
    n ++;
} 

当扫描.35金额为浮动时,实际金额值为0.3499