编辑:
我解决了这个问题,首先将浮点值乘以100,然后使用roundf()
函数将其舍入,然后将其强制转换为要存储在整数变量中的整数。我从那里开始使用整数值进行其余操作,一切正常。即使@JacobBoertjes提供的解决方案确实有效,但我的任务还是要求我使用get_float()
库中的cs50.h
,所以我没有实现它。这是最终的代码:
// Get user input as a positive float value
float f_change;
do {
printf("Change owed: ");
f_change = get_float();
} while(f_change < 0);
// Round & cast
int int_change = (int) roundf(f_change * 100);
我的程序接受一定数量的货币,例如$ 4.20,并找出可以表示该值的最小硬币数量。例如,从程序中以$ 4.20作为输入的期望输出将是:16个季度($ 4.00),2个1角硬币($ 0.20)。
我的程序成功计算了季度数,但未能成功在角钱上工作。失败的原因是代码中的第二个 for循环。 0.10> = 0.10 的计算结果不为true,因此循环的最后一次迭代永远不会发生。我究竟做错了什么?
这是代码。我提供了测试打印语句,并将其输出写为注释。
#include <stdio.h>
#include <cs50.h>
int main(void) {
// Fake user input
float owed_coin = 4.2f;
// Initialize coin variables
int coin_count = 0;
float quarters = 0.25f,
dimes = 0.10f;
// Calculate quarters
while(owed_coin >= quarters) {
owed_coin -= quarters;
coin_count += 1;
}
printf("owed_coin: %.2f\ncoin_count: %d\n\n", owed_coin, coin_count);
// Prints owed_coin: 0.20
// coin_count: 16
// Calculate dimes
while(owed_coin >= dimes) {
owed_coin -= dimes;
coin_count += 1;
}
printf("owed_coin: %.2f\ncoin_count: %d\n\n", owed_coin, coin_count);
// Prints owed_coin: 0.10
// coin_count: 17
}
答案 0 :(得分:1)
浮点比较通常不是一个好主意,因为浮点数经常变得不精确,因此将不完全相等。如@bruceg所述,一个好的解决方案是将您的货币价值保持为美分,从而避免使用浮点数。
您可以将float owed_coin = 4.2f;
替换为int owed_coin = 420;
关于收集用户输入此号码的建议,这是我对scanf
的建议
int n1, n2;
printf("Please enter amount:");
scanf("%d.%2d", &n1, &n2);
owed_coin = n1*100 + n2;
另一种解决方案使您可以将变量保持为浮点数,并且只需比较两者之间的很小差异即可。可以在这里找到:What's wrong with using == to compare floats in Java?
它使用Java Math库,但是类似的解决方案在C语言中可能看起来像这样:
while((owed_coin - dimes) >= -0.001) {
owed_coin -= dimes;
coin_count += 1;
}
如果您想更多地了解为什么浮点数会遭受小的无利可图,请查看以下内容:https://en.wikipedia.org/wiki/Floating-point_arithmetic#Accuracy_problems