簡體   English   中英

C while循環不停止

[英]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

http://floating-point-gui.de/

正如其他人所說,這是一個浮點問題。 這是您的問題:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM