2017-04-05 105 views
2

我是一个初学者,这是(的简化版本)的代码,我写这封信的部分:C,而环棘手异常

1.prompt用户输入一个数字(浮动金额),让用户说将只有数量是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,而不是返回到循环并且最后一次循环。

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

+4

相关:是浮点数学破? –

+0

切勿使用浮点进行货币计算。浮点不适用于货币,会导致结果错误,不准确,有时甚至是非法的。使用整数来计算分数并检查你的法则对四舍五入的说法。即使只是学习或编写示例代码,也会养成正确的做法。试着让数字正确合计,而愤怒的会计师在每个月的午夜前45分钟就会对你大喊大叫,这并不好玩(特别是当它是某人时elses代码)。 – Art

回答

0

由于底层推理是正确的,因此在代码中没有严格意义上的错误;但请注意,值0.35不能完全代表float数据类型,这同样适用于0.05;作为划分(基本上是问题中代码的语义)是通过重复减法来实现的,由于不能准确地表示期望值而导致的误差累积。结果是减法的次数不同于分析预期的结果,因为终止条件太快了。数据类型float不适用于财务计算,即使在这样一个非常小的日常示例中。

这太可怕了,但这是事实。

+0

感谢Codor的解释,我现在明白了,不会在这种情况下再次使用float) – cashmisa

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向我展示了当使用'double'变量(不是float),$ 0.57转换为(long)56时,使用floor()不起作用,使用$ 0.57作为输入!他提供了代码,我简直不敢相信我的眼睛!

+0

我明白了,谢谢Lyall Pearce,这非常有帮助!我会牢记未来的浮点四舍五入:) – cashmisa

+0

如果我要编辑,我会用int()而不是round(),但看着你的建议,我查了一下差异并学习了一些。再次感谢。 – cashmisa

-1

我发现了一个修复程序。这是工作

enter code here 

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

while scan .35 amount as float the actual amount value is 0。3499

+1

这是一个肮脏,笨拙的解决方法,不是修复! – cmaster