2017-04-05 78 views
2

我是一個初學者,這是(的簡化版本)的代碼,我寫這封信的部分:C,而環棘手異常

1.prompt用戶輸入一個數字(浮動金額),讓用戶說將只有數量是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,而不是返回到循環並且最後一次循環。

出了什麼問題?請幫助...非常感謝您的時間!

+4

相關:是浮點數學破? –

+0

切勿使用浮點進行貨幣計算。浮點不適用於貨幣,會導致結果錯誤,不準確,有時甚至是非法的。使用整數來計算分數並檢查你的法則對四捨五入的說法。即使只是學習或編寫示例代碼,也會養成正確的做法。試着讓數字正確合計,而憤怒的會計師在每個月的午夜前45分鐘就會對你大喊大叫,這並不好玩(特別是當它是某人時elses代碼)。 – Art

回答

0

由於底層推理是正確的,因此在代碼中沒有嚴格意義上的錯誤;但請注意,值0.35不能完全代表float數據類型,這同樣適用於0.05;作爲劃分(基本上是問題中代碼的語義)是通過重複減法來實現的,由於不能準確地表示期望值而導致的誤差累積。結果是減法的次數不同於分析預期的結果,因爲終止條件太快了。數據類型float不適用於財務計算,即使在這樣一個非常小的日常示例中。

這太可怕了,但這是事實。

+0

感謝Codor的解釋,我現在明白了,不會在這種情況下再次使用float) – cashmisa

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向我展示了當使用'double'變量(不是float),$ 0.57轉換爲(long)56時,使用floor()不起作用,使用$ 0.57作爲輸入!他提供了代碼,我簡直不敢相信我的眼睛!

+0

我明白了,謝謝Lyall Pearce,這非常有幫助!我會牢記未來的浮點四捨五入:) – cashmisa

+0

如果我要編輯,我會用int()而不是round(),但看着你的建議,我查了一下差異並學習了一些。再次感謝。 – cashmisa

-1

我發現了一個修復程序。這是工作

enter code here 

while ((amount - 0.0499) >= 0) 
{ 
    amount -= 0.05; 
    n ++; 
} 

while scan .35 amount as float the actual amount value is 0。3499

+1

這是一個骯髒,笨拙的解決方法,不是修復! – cmaster