我的简短C代码中的小错误。 为什么?

我无法弄清楚为什么这对90%的输入起作用,而不是其他输入。 这是为了告诉你在变化中会得到多少硬币。 大多数测试数量都可以正常工作,但是如果输入4.20(或4.20美元),它将返回23个硬币……它应该是18个硬币(16个季度和2个镍币)。 这个bug在哪里? 这是我的代码:

#include  #include  int main(void){ float change = 0.00; printf("How much change is owed? "); change = GetFloat(); float quarters = change/.25; change-= (int)quarters*.25; float dimes = change/.10; change-= (int)dimes*.10; float nickels = change/.05; change-= (int)nickels*.05; float pennies = (change+.005)/.01; change-=(int)pennies*.01; int total = (int)quarters+(int)dimes+(int)nickels+(int)pennies; printf("%d\n", total); return 0; } 

抛出浮点计算。 这完全基于百分之一,所以只需使用整数除法/模数。 永远不要依赖浮点数的完美准确性。

 #include  #include  int main(void){ float fchange = 0.00; int change = 0; printf("How much change is owed? "); fchange = GetFloat(); change = (int)roundf(fchange*100.0); int quarters = change/25; change = change % 25; int dimes = change/10; change = change % 10; int nickels = change/5; change = change % 5; printf("%d quarters, %d dimes, %d nickels, %d pennies\n", quarters, dimes, nickels, change); return 0; } 

最接近float4.20略小于(4.19999980926513671875,对于通常的32位IEEE754 float )。 因此,在你减去16个季度的4美元之后,你剩下的数量略小于0.2。 将其除以0.1会产生略小于2的值,因此您的nickels值为1.当您减去镍后,该值稍微小于0.1,除以0.05会导致略小于2的商。

您应该仅使用整数进行此类计算,以美分计算。

其他答案主要包括:你应该在这里使用固定点,而不是浮点。 但是,当从浮点输入到固定点表示时,要小心圆。 这是我破解的一个简短版本,它适用于所有积极的输入:

 #include  #include  int main(int argc, char ** argv) { float change = atof(argv[1]); int work = (int)(100*change+0.5); int quarters, dimes, nickels, pennies; quarters = work/25; work %= 25; dimes = work/10; work %= 10; nickels = work/5; work %= 5; pennies = work; printf("%.2f dollars = %d quarters, %d dimes, %d nickels and %d pennies: %d coins total\n", change, quarters, dimes, nickels, pennies, quarters+dimes+nickels+pennies); return 0; } 

例如:

 ./change 4.20 4.20 dollars = 16 quarters, 2 dimes, 0 nickels and 0 pennies: 18 coins total