《入门经典》——6.25

非线性方程求根:

  一次向银行借a元钱,分b月还清。如果需要每月还c元,月利率是多少(按复利计算)?例如借2000元,分4个月还每月510元,则月利率为0.797%。答案不应超过100%。

  分析:首先我们先从数学的角度来理解题意,需要注意的是,这里所谓复利的意思应该是指每个月涨息之后然后还贷,这样是非常便利我们列出计算方程的。

  以样例为例,我们可以列入如下的方程,设利率是x:

  (((2000(1+x)-c)(1+x)-c)(1+x)-c)(1+x)-c = 0.

  可以看到这是一个非线性方程,而且对于不同的月数b,这个方程左边的长度还会不同,因此我们应该果断放弃从函数的角度来求解这个方程的根。

  结合简单的函数知识,我们知道函数零点-方程根是通解的,因此我们可以将根视为函数f(a,b,c,rate)的零点,然后在区间[0,100]枚举rate来求得这个方程的零点。

  非常需要注意的是,在利用二分求零点的时候,非常有必要分析一下函数自身的单调性,因为这将直接影响根据计算结果继续二分区间,而结合这道题目,容易看到函数是单调递增的。

  简单的参考代码如下:

 #include<iostream>

#include<cstdio>

using namespace std;

 

double f(double money,int month , double monthlyment,double rate)

{

 

    while(month--)

    {

        money = money*(1+rate/100.0);

        money -= monthlyment;

    }

 

 

    return  money;

}

int main()

{

    double money , monthlypayment , rate;

    int month;

    printf("Input money,month,monthlypayment:
");

    scanf("%lf %d %lf",&money,&month,&monthlypayment);

 

    double hi , lo;

    hi = 100.0 , lo = 0.0;

    while(hi - lo > 1e-5)

    {

        double mid = (hi + lo)/2.0;

       // printf("%lf",mid);

        if(f(money,month,monthlypayment,mid) > 0)

              hi = mid;

        else

              lo = mid;

    }

    printf("rate(monthly) : %.3lf%%
",lo);

}
原文地址:https://www.cnblogs.com/rhythmic/p/5615810.html