我是初学者,这是我写的代码的一部分(简化版):
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,而不是回到循环并最后一次循环。
出了什么问题?请帮忙......非常感谢您的时间!
答案 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.35
,float
也是如此;作为划分(基本上是问题中代码的语义)是通过重复减法实现的,由无法准确表示所需值引起的误差累积。结果是减法的数量与分析预期的结果不同,因为终止条件太快达到。 0.05
数据类型不适用于财务计算,即使在如此非常小的日常示例中也是如此。
这太糟糕了,但实际上是这样。
答案 2 :(得分:-1)
我找到了解决办法。这是有效的
enter code here
while ((amount - 0.0499) >= 0)
{
amount -= 0.05;
n ++;
}
当扫描.35金额为浮动时,实际金额值为0.3499