Java:等额本息还款计算

首先我们推导下等额本息还款的还款公式。

以下数据已知:

贷款总额: A A A
贷款期限(月): m m m
贷款年利率: P P P
贷款月利率: p = P / 12 p = P / 12 p=P/12

求等额本息方式每月还款额,和每月还款的本金利息分别多少。


第1个月产生的利息为 b 1 = A ∗ p b_1=A*p b1=Ap,设每月还款额为 x x x,显然 x > b 1 x>b_1 x>b1

a 1 = x − b 1 a_1=x-b_1 a1=xb1,则第2个月产生的利息为 b 2 = ( A − a 1 ) ∗ p b_2=(A-a_1)*p b2=(Aa1)p

a 2 = x − b 2 a_2=x-b_2 a2=xb2,可得:

(1) { b 1 − b 2 = A ∗ p − ( A − a 1 ) ∗ p a 2 − a 1 = ( x − b 2 ) − ( x − b 1 ) \left\{ \begin{array}{l} b_1-b_2=A*p-(A-a_1)*p \\ a_2-a1=(x-b_2)-(x-b_1) \end{array} \right. \tag{1} {b1b2=Ap(Aa1)pa2a1=(xb2)(xb1)(1)

( 1 ) (1) (1)可得:
a 2 = a 1 ( 1 + p ) a_2=a_1(1+p) a2=a1(1+p)

同样道理,我们依次可以推得:
{ a 3 = a 2 ( 1 + p ) = a 1 ∗ ( 1 + p ) 2 a 4 = a 3 ( 1 + p ) = a 1 ∗ ( 1 + p ) 3 . . . a m = a m − 1 ( 1 + p ) = a 1 ∗ ( 1 + p ) m − 1 \left\{ \begin{array}{l} a_3=a_2(1+p)=a_1*(1+p)^2 \\ a_4=a_3(1+p)=a_1*(1+p)^3 \\ ... \\ a_m=a_{m-1}(1+p)=a_1*(1+p)^{m-1} \\ \end{array} \right. a3=a2(1+p)=a1(1+p)2a4=a3(1+p)=a1(1+p)3...am=am1(1+p)=a1(1+p)m1

当还款期限满时,我们应该正好将贷款全部的本金和利息还清,所以有:
∑ i = 1 m a i = A \sum_{i=1}^m a_i=A i=1mai=A

可以看出求 a 1 a_1 a1其实就是简单的等差数列求和问题,我写下过程:
{ A = a 1 + a 1 ∗ ( 1 + p ) + a 1 ∗ ( 1 + p ) 2 + . . . + a 1 ∗ ( 1 + p ) m − 1 ( 1 + p ) ∗ A = a 1 ∗ ( 1 + p ) + a 1 ∗ ( 1 + p ) 2 + . . . + a 1 ∗ ( 1 + p ) m \left\{ \begin{array}{l} A=a_1+a_1*(1+p)+a_1*(1+p)^2+...+a_1*(1+p)^{m-1} \\ (1+p)*A=a_1*(1+p)+a_1*(1+p)^2+...+a_1*(1+p)^m \\ \end{array} \right. {A=a1+a1(1+p)+a1(1+p)2+...+a1(1+p)m1(1+p)A=a1(1+p)+a1(1+p)2+...+a1(1+p)m
两式相减并化简可得:
a 1 = A ∗ p ( 1 + p ) m − 1 a_1=\dfrac{A*p}{(1+p)^m-1} a1=(1+p)m1Ap

结合上面第1月的利息 b 1 b_1 b1,就能推出 x x x了,下面给出Java代码:

/**
 * 等额本息还款金额计算类
 */
public class DK {
  private double A; // 贷款总额
  private double P; // 年利率
  private double p; // 月利率
  private int m; // 贷款期限(月)

  private double a1; // 第1个月所还本金
  private double b1; // 第1个月所还利息
  private double x; // 每月所还金额

  /**
   * @param A
   *          贷款总额
   * @param m
   *          贷款期限(月)
   * @param P
   *          年利率
   */
  public DK(double A, int m, double P) {
    this.A = A;
    this.m = m;
    this.P = P;
    this.p = this.P / 12;

    this.b1 = A * p;
    this.a1 = A * p / (Math.pow(1 + p, m) - 1);
    this.x = a1 + b1;
  }

  public static void main(String[] args) {
    double A = 50 * 10000.0;
    double P = 0.05;
    int m = 360;

    DK dk = new DK(A, m, P);
    System.out.println(String.format("%.2f", dk.getX()));

    for (int i = 1; i < 4; i++) {
      System.out.println(String.format("%.2f, %.2f", dk.getAi(i), dk.getBi(i)));
    }
  }

  /**
   * @return 每月所还金额
   */
  public double getX() {
    return this.x;
  }

  /**
   * @param i
   *          月份
   * @return 返回第i个月所还本金
   */
  public double getAi(int i) {
    return this.a1 * Math.pow(1 + p, i - 1);
  }

  /**
   * @param i
   *          月份
   * @return 返回第i个月所还利息
   */
  public double getBi(int i) {
    return this.x - getAi(i);
  }

  /**
   * @param i
   *          月份
   * @return 返回到第i月所还本金总和
   */
  public double getASum(int i) {
    double sum = 0.0;
    for (int j = 1; j <= i; j++) {
      sum += getAi(j);
    }
    return sum;
  }

  /**
   * @param i
   *          月份
   * @return 返回到第i月所还利息总和
   */
  public double getBSum(int i) {
    double sum = 0.0;
    for (int j = 1; j <= i; j++) {
      sum += getBi(j);
    }
    return sum;
  }
}
  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值