2016-03-07 36 views
1

我很確定我是這樣做的,但顯然我不是。這個while循環在達到0時會一直保持無限運行。它會一遍又一遍地輸出「每月支付:$ 0.00」和「您的貸款在$ 0.00之後」。我究竟做錯了什麼?這個while循環(C++)有什麼問題?

while (loan_balance ! = 0) 
    { 
    monthly_payment = loan_balance/20; 
    loan_balance = loan_balance - monthly_payment; 

    cout << "Monthly Payment: $" << monthly_payment << ends; 
    cout << "Your loan balance after that payment is: $" << loan_balance << endl; 
    } 
+0

你與調試器步?是'monthly_payment'曾經'0',如果是這樣你不會改變'loan_balance' – CoryKramer

+1

什麼變量類型是'loan_balance'和'monthly_payment'? –

+1

@NoamHacker他們都是雙打類型。 – Bluasul

回答

0

loan_balance可能是一個float或double;它可能會降低到接近但不完全爲0.將您的比較更改爲「> 0」。

+0

它仍然會返回true,loan_balance仍然會高於0,同樣的問題。 –

+0

這也行不通。 – Paulo1205

4

如果load_balance是浮點型(floatdouble),然後load_balance != 0(其中00.0f)可能永遠不會是假的,除非它明確設置爲load_balance = 0.0f。所以它應該與一個小的閾值進行比較,例如,

while(load_balance >= 1e-4) 

同樣,不等於操作符是!=,用空格! =是不起作用。

0

的類型是int

0.0F的數據類型double類型的數據類型或float

所以你說

while(loan_balance != 0) 
    do stuff 

的編譯器回覆說:「loan_balance永遠不會永遠是如果是雙/浮動,所以我會繼續做東西。「

請記住:整數不花車/雙打

+3

正確的錯誤原因。你可以比較浮點數和整數,但你必須知道浮點數是不精確的,所以精確的相等性不太可能。 – user4581301

+0

好點。 @ user4581301 – 2016-03-12 17:26:24

0

你loan_balance是最有可能從未真正將是0準確。我很確定你希望你的貸款餘額浮動或雙重。

double loan_balance=23000.00; 
while (loan_balance >0.000) 
    { 
    monthly_payment = loan_balance/20.0; 
    loan_balance = loan_balance - monthly_payment; 

    cout << "Monthly Payment: $" << monthly_payment << ends; 
    cout << "Your loan balance after that payment is: $" << loan_balance << endl; 
    } 
0

您正面臨精度和舍入的問題。

當你指數地減少一個數字時,它會收斂到零。如果它是一個有限精度的浮點數,將會有一個很小的數字,以任何可能的表示都無法與零區分。所以,像

double d=1.0; // or some other finite value 
while(d!=0.0) 
    d*=ratio; // ratio is some finite value so that fabs(ratio)<1.0 

將完成在有限的迭代次數。

然而,取決於dratio,特別是當d在低於正常範圍接近零的值(這意味着較少的顯著位)和fabs(ratio)接近1.0(收斂速度慢),所選擇的舍入模式可以引起d*ratio是向d四捨五入。當發生這種情況時,上面的循環將永遠不會結束。

在支持IEC 60559的機器/編譯器中,您應該能夠使用fegetround()fesetround()(在<fenv.h>中聲明)測試和設置浮點舍入模式。系統上的默認舍入很可能是最接近的。對於上面的循環更快地收斂(或根本),最好是使得舍入趨向於0.

但是請注意,它帶有一個價格:根據應用程序的不同,舍入模式可能會不同基於精度/準確性(OTOH,如果您已經在低於正常範圍內工作,您的精度可能不再那麼好),這是不理想的。

但原來的問題的銜接問題仍然比較複雜一點,因爲它是一個兩步操作完成。所以在除法操作中有一個四捨五入的結果,另一個在減法中。爲了增加收斂的機會和速度,減法應該儘可能多地取儘可能多的值,所以在這種情況下,四捨五入會更好。實際上,當我在OP的原始代碼中加上fesetround(FP_UPWARD)(連同定義loan_balance的初始值到1.0),它在14466次迭代之後收斂。 (然而要注意,這只是一個猜測,並在原代碼的影響可能是隻是一個特殊的條件。更深入的分析,有必要限定它,而這樣的分析必須考慮到比的不同的值,和被減數和減數的相對偉大。)