首先我们推导下等额本息还款的还款公式。
以下数据已知:
贷款总额:
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=A∗p,设每月还款额为 x x x,显然 x > b 1 x>b_1 x>b1。
令 a 1 = x − b 1 a_1=x-b_1 a1=x−b1,则第2个月产生的利息为 b 2 = ( A − a 1 ) ∗ p b_2=(A-a_1)*p b2=(A−a1)∗p。
令 a 2 = x − b 2 a_2=x-b_2 a2=x−b2,可得:
(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} {b1−b2=A∗p−(A−a1)∗pa2−a1=(x−b2)−(x−b1)(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=am−1(1+p)=a1∗(1+p)m−1
当还款期限满时,我们应该正好将贷款全部的本金和利息还清,所以有:
∑
i
=
1
m
a
i
=
A
\sum_{i=1}^m a_i=A
i=1∑mai=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)m−1(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)m−1A∗p
结合上面第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;
}
}