废话说在前头,本人公司做银行APP,每次写到贷款计算器总是一遍又一遍研究计算公式。N次过后,还是决定写一篇blog分享给大家。
注:利率一律按照4.9计算。所有计算结果参照在线贷款计算公式
1 等额本息
每月还款本金+利息一样。
贷款本金100万,贷款期限30年,贷款利息91万元(近似值),那么月供191万元/360月。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
public static String[] calculateEqualPrincipalAndInterest(double principal, int months, double rate) { ArrayList<String> data = new ArrayList<String>(); double monthRate = rate / (100 * 12); double preLoan = (principal * monthRate * Math.pow((1 + monthRate), months)) / (Math.pow((1 + monthRate), months) - 1); double totalMoney = preLoan * months; double interest = totalMoney - principal; data.add(FORMAT.format(totalMoney)); data.add(FORMAT.format(principal)); data.add(FORMAT.format(interest)); data.add(FORMAT.format(preLoan)); data.add(String.valueOf(months)); return data.toArray(new String[data.size()]); }
|
运行结果:
在线计算结果:
2 等额本金
贷款本金100万,贷款期限30年。每月还款本金=100万/360月,每月还款利息=剩余贷款金额*月利率。所以每月利息递减。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
public static String[] calculateEqualPrincipal(double principal, int months, double rate) { ArrayList<String> data = new ArrayList<String>(); double monthRate = rate / (100 * 12); double prePrincipal = principal / months; double firstMonth = prePrincipal + principal * monthRate; double decreaseMonth = prePrincipal * monthRate; double interest = (months + 1) * principal * monthRate / 2; double totalMoney = principal + interest; data.add(FORMAT.format(totalMoney)); data.add(FORMAT.format(principal)); data.add(FORMAT.format(interest)); data.add(FORMAT.format(firstMonth)); data.add(FORMAT.format(decreaseMonth)); data.add(String.valueOf(months)); return data.toArray(new String[data.size()]); }
|
运行结果:
在线计算结果:
3 提前还款
当客户有足够的钱偿还贷款本金时,可以向银行申请提前还款。
3.1 全部提前还款
一次性结清贷款
3.1.1 等额本息
扣除之前每月还款的本金(前期还款时,利息占月供很大的比例),剩余贷款金额加上一个月利息即支付金额。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
|
public static String[] calculateEqualPrincipalAndInterest(double principal, int months, int payTimes, double rate) { ArrayList<String> data = new ArrayList<String>(); double monthRate = rate / (100 * 12); double preLoan = (principal * monthRate * Math.pow((1 + monthRate), months)) / (Math.pow((1 + monthRate), months) - 1); double totalMoney = preLoan * months; double interest = totalMoney - principal; double leftLoan = principal * Math.pow(1 + monthRate, payTimes) - preLoan * (Math.pow(1 + monthRate, payTimes) - 1) / monthRate; double payLoan = principal - leftLoan; double payTotal = preLoan * payTimes; double payInterest = payTotal - payLoan; double totalPayAhead = leftLoan * (1 + monthRate); double saveInterest = totalMoney - payTotal - totalPayAhead; data.add(FORMAT.format(totalMoney)); data.add(FORMAT.format(principal)); data.add(FORMAT.format(interest)); data.add(FORMAT.format(preLoan)); data.add(FORMAT.format(payTotal)); data.add(FORMAT.format(payLoan)); data.add(FORMAT.format(payInterest)); data.add(FORMAT.format(totalPayAhead)); data.add(FORMAT.format(saveInterest)); data.add(String.valueOf(0)); return data.toArray(new String[data.size()]); }
|
已还款10次,运行结果:
在线计算运行结果:
由此可以看出,前10次还款,扣除本金只占20%左右。
3.1.2 等额本金
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
|
public static String[] calculateEqualPrincipal(double principal, int months, int payTimes, double rate) { ArrayList<String> data = new ArrayList<String>(); double monthRate = rate / (100 * 12); double prePrincipal = principal / months; double firstMonth = prePrincipal + principal * monthRate; double decreaseMonth = prePrincipal * monthRate; double interest = (months + 1) * principal * monthRate / 2; double totalMoney = principal + interest; double payLoan = prePrincipal * payTimes; double payInterest = (principal * payTimes - prePrincipal * (payTimes - 1) * payTimes / 2) * monthRate; double payTotal = payLoan + payInterest; double totalPayAhead = (principal - payLoan) * (1 + monthRate); double saveInterest = totalMoney - payTotal - totalPayAhead; data.add(FORMAT.format(totalMoney)); data.add(FORMAT.format(principal)); data.add(FORMAT.format(interest)); data.add(FORMAT.format(firstMonth)); data.add(FORMAT.format(decreaseMonth)); data.add(FORMAT.format(payTotal)); data.add(FORMAT.format(payLoan)); data.add(FORMAT.format(payInterest)); data.add(FORMAT.format(totalPayAhead)); data.add(FORMAT.format(saveInterest)); data.add(String.valueOf(0)); return data.toArray(new String[data.size()]); }
|
已还款10次,运行结果:
在线计算运行结果:
对比等额本息,已偿还本金占还款金额30%左右。
3.2 部分提前还款
3.2.1 保持月供不变
3.2.1.1 等额本息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
|
public static String[] calculateEqualPrincipalAndInterestApart(double principal, int months, double aheadPrincipal, int payTimes, double rate) { ArrayList<String> data = new ArrayList<String>(); double monthRate = rate / (100 * 12); double preLoan = (principal * monthRate * Math.pow((1 + monthRate), months)) / (Math.pow((1 + monthRate), months) - 1); double totalMoney = preLoan * months; double interest = totalMoney - principal; double leftLoanBefore = principal * Math.pow(1 + monthRate, payTimes) - preLoan * (Math.pow(1 + monthRate, payTimes) - 1) / monthRate; double leftLoan = principal * Math.pow(1 + monthRate, payTimes + 1) - preLoan * (Math.pow(1 + monthRate, payTimes + 1) - 1) / monthRate-aheadPrincipal; double payLoan = principal - leftLoanBefore; double payTotal = preLoan * payTimes ; double payInterest = payTotal - payLoan; double aheadTotalMoney = aheadPrincipal + preLoan; int leftMonth = (int) Math.floor(Math.log(preLoan / (preLoan - leftLoan * monthRate)) / Math.log(1 + monthRate)); double newPreLoan = (leftLoan * monthRate * Math.pow((1 + monthRate), leftMonth)) / (Math.pow((1 + monthRate), leftMonth) - 1); double leftTotalMoney = newPreLoan * leftMonth; double leftInterest = leftTotalMoney - (leftLoan-aheadPrincipal); double saveInterest = totalMoney - aheadTotalMoney - leftTotalMoney-payTotal; data.add(FORMAT.format(totalMoney)); data.add(FORMAT.format(principal)); data.add(FORMAT.format(interest)); data.add(FORMAT.format(preLoan)); data.add(FORMAT.format(payTotal)); data.add(FORMAT.format(payLoan)); data.add(FORMAT.format(payInterest)); data.add(FORMAT.format(aheadTotalMoney)); data.add(FORMAT.format(leftTotalMoney)); data.add(FORMAT.format(leftInterest)); data.add(FORMAT.format(newPreLoan)); data.add(FORMAT.format(saveInterest)); data.add(String.valueOf(leftMonth)); return data.toArray(new String[data.size()]); }
|
贷款100万,提前还款50万。首次还款:17年8月,提前还款:18年6月。已还次数10次是截止到18年5月。剩余贷款,保持月供不变(大致维持不变),后续需还款114期(9年零6月),所以提前还款后还款日期:18年7月~27年12月。
运行结果:
在线计算结果:(这里有1个月的误差)
3.2.1.2 等额本金
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
public static String[] calculateEqualPrincipalApart(double principal, int months, double aheadPrincipal, int payTimes, double rate) { ArrayList<String> data = new ArrayList<String>(); double monthRate = rate / (100 * 12); double prePrincipal = principal / months; double firstMonth = prePrincipal + principal * monthRate; double decreaseMonth = prePrincipal * monthRate; double interest = (months + 1) * principal * monthRate / 2; double totalMoney = principal + interest; double payLoan = prePrincipal * payTimes; double payInterest = (principal * payTimes - prePrincipal * (payTimes - 1) * payTimes / 2) * monthRate; double payTotal = payLoan + payInterest; double aheadTotalMoney = (principal - payLoan) * monthRate+aheadPrincipal+prePrincipal; double leftLoan = principal - aheadPrincipal - payLoan-prePrincipal; int leftMonth = (int) Math.floor(leftLoan / prePrincipal); double newPrePrincipal = leftLoan / leftMonth; double newFirstMonth = newPrePrincipal + leftLoan * monthRate; double newDecreaseMonth = newPrePrincipal * monthRate; double leftInterest = (leftMonth + 1) * leftLoan * monthRate / 2; double leftTotalMoney = leftLoan + leftInterest; double saveInterest = totalMoney-payTotal-aheadTotalMoney-leftTotalMoney; data.add(FORMAT.format(totalMoney)); data.add(FORMAT.format(principal)); data.add(FORMAT.format(interest)); data.add(FORMAT.format(firstMonth)); data.add(FORMAT.format(decreaseMonth)); data.add(FORMAT.format(payTotal)); data.add(FORMAT.format(payLoan)); data.add(FORMAT.format(payInterest)); data.add(FORMAT.format(aheadTotalMoney)); data.add(FORMAT.format(leftTotalMoney)); data.add(FORMAT.format(leftInterest)); data.add(FORMAT.format(newFirstMonth)); data.add(FORMAT.format(newDecreaseMonth)); data.add(FORMAT.format(saveInterest)); data.add(String.valueOf(leftMonth)); return data.toArray(new String[data.size()]); }
|
贷款100万,还款10期后,提前还款50万。
运行结果:
在线计算结果:
3.2.2 保持期数不变
3.2.2.1 等额本息
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
|
public static String[] calculateEqualPrincipalAndInterestApart2(double principal, int months, double aheadPrincipal, int payTimes, double rate) { ArrayList<String> data = new ArrayList<String>(); double monthRate = rate / (100 * 12); double preLoan = (principal * monthRate * Math.pow((1 + monthRate), months)) / (Math.pow((1 + monthRate), months) - 1); double totalMoney = preLoan * months; double interest = totalMoney - principal; double leftLoanBefore = principal * Math.pow(1 + monthRate, payTimes ) - preLoan * (Math.pow(1 + monthRate, payTimes ) - 1) / monthRate; double leftLoan = principal * Math.pow(1 + monthRate, payTimes + 1) - preLoan * (Math.pow(1 + monthRate, payTimes + 1) - 1) / monthRate; double payLoan = principal - leftLoanBefore; double payTotal = preLoan * payTimes; double payInterest = payTotal - payLoan; double aheadTotalMoney = preLoan + aheadPrincipal; double newPreLoan = ((leftLoan - aheadPrincipal) * monthRate * Math.pow((1 + monthRate), months - payTimes - 1)) / (Math.pow((1 + monthRate), months - payTimes - 1) - 1); double leftTotalMoney = newPreLoan*(months-payTimes); double leftInterest =leftTotalMoney -(leftLoan - aheadPrincipal); double saveInterest = totalMoney-payTotal-aheadTotalMoney-leftTotalMoney; data.add(FORMAT.format(totalMoney)); data.add(FORMAT.format(principal)); data.add(FORMAT.format(interest)); data.add(FORMAT.format(preLoan)); data.add(FORMAT.format(payTotal)); data.add(FORMAT.format(payLoan)); data.add(FORMAT.format(payInterest)); data.add(FORMAT.format(aheadTotalMoney)); data.add(FORMAT.format(leftTotalMoney)); data.add(FORMAT.format(leftInterest)); data.add(FORMAT.format(newPreLoan)); data.add(FORMAT.format(saveInterest)); data.add(String.valueOf(months)); return data.toArray(new String[data.size()]); }
|
运行结果:
在线计算结果:
3.2.2.2 等额本金
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
|
public static String[] calculateEqualPrincipalApart2(double principal, int months, double aheadPrincipal, int payTimes, double rate) { ArrayList<String> data = new ArrayList<String>(); double monthRate = rate / (100 * 12); double prePrincipal = principal / months; double firstMonth = prePrincipal + principal * monthRate; double decreaseMonth = prePrincipal * monthRate; double interest = (months + 1) * principal * monthRate / 2; double totalMoney = principal + interest; double payLoan = prePrincipal * payTimes; double payInterest = (principal * payTimes - prePrincipal * (payTimes - 1) * payTimes / 2) * monthRate; double payTotal = payLoan + payInterest; double aheadTotalMoney = (principal - payLoan) * monthRate+aheadPrincipal+prePrincipal; int leftMonth = months - payTimes-1; double leftLoan = principal - aheadPrincipal - payLoan-prePrincipal; double newPrePrincipal = leftLoan / leftMonth; double newFirstMonth = newPrePrincipal + leftLoan * monthRate; double newDecreaseMonth = newPrePrincipal * monthRate; double leftInterest = (leftMonth + 1) * leftLoan * monthRate / 2; double leftTotalMoney = leftLoan + leftInterest; double saveInterest = totalMoney-payTotal-aheadTotalMoney-leftTotalMoney; data.add(FORMAT.format(totalMoney)); data.add(FORMAT.format(principal)); data.add(FORMAT.format(interest)); data.add(FORMAT.format(firstMonth)); data.add(FORMAT.format(decreaseMonth)); data.add(FORMAT.format(payTotal)); data.add(FORMAT.format(payLoan)); data.add(FORMAT.format(payInterest)); data.add(FORMAT.format(aheadTotalMoney)); data.add(FORMAT.format(leftTotalMoney)); data.add(FORMAT.format(leftInterest)); data.add(FORMAT.format(newFirstMonth)); data.add(FORMAT.format(newDecreaseMonth)); data.add(FORMAT.format(saveInterest)); data.add(String.valueOf(months)); return data.toArray(new String[data.size()]); }
|
运行结果:
在线计算结果:
测试数据:
贷款100万
部分提前还款50万
已偿还10期
贷款利率4.9
贷款期限30年
觉得有用?那打赏一个呗。[去打赏](/donate/)