[英]C while-loop not stopping
#include <cs50.h>
#include <stdio.h>
int main(void) {
printf("Enter your change: ");
int pennies = 0, nickels = 0, dimes = 0, quarters = 0;
float change = GetFloat();
while (change > 0) {
if (change >= 0.25) {
quarters++;
change -= 0.25;
}
else if (change >= 0.10) {
dimes++;
change -= 0.10;
}
else if (change >= 0.05) {
nickels++;
change -= 0.05;
}
else if (change >=0.01) {
pennies++;
change -= 0.01;
}
// force break
else {
printf("%1.2f - Num. of change left\n", change);
break;
}
}
printf("Quarters: %d\n", quarters);
printf("Dimes: %d\n", dimes);
printf("Nickels: %d\n", nickels);
printf("Pennies: %d\n", pennies);
return 0;
}
您好,我目前是C語言的新手,並且正在上哈佛大學的CS50課程。 在不停止while循環的情況下,“ change”變量似乎下降到0.00。 這迫使我在最后輸入“ break”。 我的代碼有什么問題?
順便說一下,這是來自問題集1。
在計算機內存中如何表示浮點數存在問題。 簡而言之:並非所有數字都可以精確存儲。 請閱讀此頁面以獲取更多詳細信息: http : //en.wikipedia.org/wiki/Floating_point#Accuracy_problems
您可以使用此服務來檢查計算機中浮點數的表示形式: http : //www.binaryconvert.com/result_float.html
關於您的情況,假設您輸入了0.4。 這意味着應將其分為0.25 + 0.1 + 0.05。 並且change
應該為零,但是:
0.40 == 0.4000000059604644775390625000,
minus
0.25 == 0.2500000000000000000000000000 (exact),
minus
0.10 == 0.1000000014901161193847656250,
minus
0.05 == 0.0500000007450580596923828125
is
0.00 == 0.0000000037252902984619140625
如您所見,最終結果略高於零,這可以防止循環結束。
通常,如果您需要數錢,則應該使用int
來計算“分”。 還是自定義類型。 還是長算術。 . 還是什么,但不是浮動點,因為大多數國家的貨幣在一個點之后只需要兩個頭寸,因此該點不必是 。
您不應使用浮點數來表示本質上必不可少的數字。 浮點運算在這里是一個問題。 在大多數情況下, Change
永遠不會等於0。您應該只對整數做所有事情,它將起作用。 算法看起來不錯。
http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html
正如其他人所說,這是一個浮點問題。 這是您的問題:
else if (change >=0.01) {
pennies++;
change -= 0.01;
}
可能發生的情況是, change
最終比0.01稍微高一點,因此當您從中減去0.01時,它最終大於零,但小於0.01,並且沒有if
子句可以處理這種情況。永遠持續下去。 您的printf()
顯示為零,因為您將其四舍五入到兩位小數,因此它看起來像是0.00,即使它可能是0.00001左右。
如此處多次所述,使用浮點數是不明智的...
但是從邏輯上講,您可以做您想做的事情,而且我懷疑這與C語言中的比較和升級規則有關...但是我想這將解決您的問題:
while (change > 0.0f)
這樣您就可以像類型一樣進行比較...
實際上,您應該更改為使用int,long或long long ...並代表美分而不是美元。
未經測試,但是這是我寫的方式。 它使用int
而不是float
來避免舍入問題,對每個硬幣具有表驅動的計算,並且進行除法而不是重復減法。
int change = GetFloat() * 100 + 0.5;
struct {const char *name; int value;} coins[] = {
{"Quarters", 25},
{"Dimes", 10},
{"Nickels", 5},
{"Pennies", 1},
};
for (int i = 0; i < 4; i++) {
int coin = change / coins[i].value;
change %= coins[i].value;
printf("%s: %d\n", coins[i].name, coin);
}
您應該使用與getFloat()等效的整數,或者使用整數變量進行比較。 由於浮點問題,代碼出錯。
#include<math.h> // for round
...
...
int change = int)100 * round(getFloat());
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.