2016-03-07 94 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次迭代之后收敛。 (然而要注意,这只是一个猜测,并在原代码的影响可能是只是一个特殊的条件。更深入的分析,有必要限定它,而这样的分析必须考虑到比的不同的值,和被减数和减数的相对伟大。)