闲来无事,将之前的一些工具类实现整理出来,以相互借鉴,共同探讨学习。

如果有发现什么不明白或者bug欢迎留言。

package com.hansy.p2p.tool;import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;/*** javadoc for com.hansy.p2p.tool.LoanCalcUtils* @Copyright: 2016xxx信息技术有限公司 * @author: roilat-D* @since: 2016年5月23日*/
public class LoanCalcUtils2 {/*** BigDecimal[0]    月应还金额* BigDecimal[1]    应还本金金额* BigDecimal[2]    应还利息金额*/private static int[] daysForPerMonthConstant = {31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30};/*** @description: 等额本息-按月份算(1)* @creator: roilat-D* @createDate: 2016年5月23日 * @modifier:* @modifiedDate:* @param loanAmt        借款金额* @param prftRat        产品利率* @param prodPerdSum    产品期数* @return* @throws Exception */public static List<BigDecimal[]> calcForEqualCapitalPlusInterestByMonth(BigDecimal loanAmt, BigDecimal prftRat, int prodPerdSum) throws Exception {/*** 等额本息的还款方式,每月的还款金额X,融资金额A,年化收益B,总期数M,月利率m* X=((A*B/12*(1+B/12)^m)/((1+B/12)^m-1)* 经过推导得到:(AB(12+B)^m)/(12*(12+m)^m-12^(m+1))* 每月所还的利息:当月本金余额*B/12* 每月所还的本金:X-每月所还的利息*/List<BigDecimal[]> results = new ArrayList<BigDecimal[]>(prodPerdSum);BigDecimal t0 = prftRat.add(new BigDecimal(12));BigDecimal t1 = ArithUtil.pow(t0, prodPerdSum);BigDecimal fz = loanAmt.multiply(prftRat).multiply(t1);BigDecimal fm = t1.multiply(new BigDecimal(12)).add(new BigDecimal(Math.pow(12, prodPerdSum+1)).negate());BigDecimal monthRepay = fz.divide(fm,6,BigDecimal.ROUND_HALF_UP);BigDecimal totalAmt = new BigDecimal("0");System.out.println("monthRepay----" + monthRepay);BigDecimal[] result;BigDecimal surplusAmt = loanAmt;//首月的剩余额为贷款总额while (prodPerdSum-- > 0) {result = new BigDecimal[3];result[0] = monthRepay;//月应还金额result[2] = surplusAmt.multiply(prftRat).divide(new BigDecimal(12),6,BigDecimal.ROUND_HALF_UP);//应还利息=剩余金额*月利率result[0] = result[0].setScale(2,BigDecimal.ROUND_HALF_UP);//四舍五入result[2] = result[2].setScale(2,BigDecimal.ROUND_HALF_UP);//四舍五入totalAmt = totalAmt.add(monthRepay.add(result[0].negate()));//计算总金额每次四舍五入的误差(6位小数)result[1] = result[0].add(result[2].negate());surplusAmt = surplusAmt.add(result[1].negate());//剩余本金=上次剩余本金-本次应还本金(两位小数)if(prodPerdSum == 0){//最后一个月result[0] = result[0].add(totalAmt.setScale(2,BigDecimal.ROUND_HALF_UP));result[1] = result[1].add(surplusAmt);result[2] = result[2].add(surplusAmt.negate()).add(totalAmt.setScale(2,BigDecimal.ROUND_HALF_UP));}results.add(result);}return results;}/*** @description: 等额本金-按月份算(2)* @creator: roilat-D* @createDate: 2016年5月24日 * @modifier:* @modifiedDate:* @param loanAmt        借款金额* @param prftRat        产品利率* @param prodPerdSum    产品期数* @return* @throws Exception*/public static List<BigDecimal[]> calcForEqualCapitalByMonth(BigDecimal loanAmt, BigDecimal prftRat, int prodPerdSum) throws Exception {/*** 等额本金的还款方式,每月的还款金额X,融资金额A,年化收益B,总期数M* 每月还款本金:A/M* 每月还款利息:上期所剩本金*B/12* X=每月还款本金+每月还款利息* */List<BigDecimal[]> results = new ArrayList<BigDecimal[]>(prodPerdSum);BigDecimal monthCapital = loanAmt.divide(new BigDecimal(prodPerdSum),6,BigDecimal.ROUND_HALF_UP);//A/M,应还本金(6位)BigDecimal totalIntAmt = new BigDecimal("0");System.out.println("monthCapital----" + monthCapital);BigDecimal[] result;BigDecimal surplusAmt = loanAmt;//首月的剩余额为贷款总额while (prodPerdSum-- > 0) {result = new BigDecimal[3];result[1] = monthCapital;//应还本金result[2] = prftRat.multiply(surplusAmt).divide(new BigDecimal(12),6,BigDecimal.ROUND_HALF_UP);//应还利息=剩余金额*月利率totalIntAmt = totalIntAmt.add(result[2].add(result[2].setScale(2, BigDecimal.ROUND_HALF_UP).negate()));//计算利息每次四舍五入的误差(6位小数)
            result[1] = result[1].setScale(2,BigDecimal.ROUND_HALF_UP);//四舍五入result[2] = result[2].setScale(2,BigDecimal.ROUND_HALF_UP);//四舍五入result[0] = result[1].add(result[2]);surplusAmt = surplusAmt.add(result[1].negate());//剩余本金=上次剩余本金-本次应还本金(两位小数)if(prodPerdSum == 0){//最后一个月result[1] = result[1].add(surplusAmt.setScale(2,BigDecimal.ROUND_HALF_UP));result[2] = result[2].add(totalIntAmt.setScale(2,BigDecimal.ROUND_HALF_UP));result[0] = result[1].add(result[2]);}results.add(result);}return results;}/*** @description: 等额本金-按天份算(3)* @creator: roilat-D* @createDate: 2016年5月24日 * @modifier:* @modifiedDate:* @param loanAmt        借款金额* @param prftRat        产品利率* @param prodPerdSum    产品期数* @param prodPerdSum    每期的天数* @return* @throws Exception*/public static List<BigDecimal[]> calcForEqualCapitalByDays(BigDecimal loanAmt, BigDecimal prftRat, int prodPerdSum, int[] daysPerMonth) throws Exception {/*** 等额本金的还款方式,每天的还款金额X,融资金额A,年化收益B,总期数M,每月天数D* 每月还款本金:A/M* 每月还款利息:上期所剩本金*B/1年天数*本期天数* X=每月还款本金+每月还款利息* */if (daysPerMonth.length != prodPerdSum) {throw new Exception("每期的天数列表和实际期数不一致!");}List<BigDecimal[]> results = new ArrayList<BigDecimal[]>(prodPerdSum);BigDecimal monthCapital = loanAmt.divide(new BigDecimal(prodPerdSum),6,BigDecimal.ROUND_HALF_UP);//A/M,应还本金
        BigDecimal[] result;BigDecimal totalIntAmt = new BigDecimal("0");BigDecimal surplusAmt = loanAmt;//首月的剩余额为贷款总额int i = 0;while (i < prodPerdSum) {result = new BigDecimal[3];result[1] = monthCapital;//应还本金result[2] = prftRat.multiply(surplusAmt).multiply(new BigDecimal(daysPerMonth[i])).divide(new BigDecimal(365),6,BigDecimal.ROUND_HALF_UP);//应还利息=剩余金额*天利率*天数totalIntAmt = totalIntAmt.add(result[2].add(result[2].setScale(2, BigDecimal.ROUND_HALF_UP).negate()));//计算利息每次四舍五入的误差(6位小数)
            result[1] = result[1].setScale(2,BigDecimal.ROUND_HALF_UP);//四舍五入result[2] = result[2].setScale(2,BigDecimal.ROUND_HALF_UP);//四舍五入result[0] = result[1].add(result[2]);surplusAmt = surplusAmt.add(result[1].negate());//剩余本金=上次剩余本金-本次应还本金(两位小数)if(prodPerdSum == i+1){//最后一个月result[1] = result[1].add(surplusAmt.setScale(2,BigDecimal.ROUND_HALF_UP));result[2] = result[2].add(totalIntAmt.setScale(2,BigDecimal.ROUND_HALF_UP));result[0] = result[1].add(result[2]);}results.add(result);i++;}return results;}/*** @description: 每月还利息,到期还本金-按月份算(4)* @creator: roilat-D* @createDate: 2016年5月24日 * @modifier:* @modifiedDate:* @param loanAmt        借款金额* @param prftRat        产品利率* @param prodPerdSum    产品期数* @return* @throws Exception*/public static List<BigDecimal[]> calcForRepayInterestPerMonthByMonth(BigDecimal loanAmt, BigDecimal prftRat, int prodPerdSum) throws Exception {/*** 每月还利息,到期还本金。每月的还款金额X,融资金额A,年化收益B,总期数M* 每月还款本金:0,最后一个月为A* 每月还款利息:A*B/12* X=每月还款本金+每月还款利息101*/List<BigDecimal[]> results = new ArrayList<BigDecimal[]>(prodPerdSum);BigDecimal[] result;BigDecimal totalIntAmt = new BigDecimal("0");while (prodPerdSum-- > 0) {result = new BigDecimal[3];if (prodPerdSum == 0) {result[1] = loanAmt;//应还本金} else {result[1] = new BigDecimal(0);//应还本金
            }result[2] = prftRat.multiply(loanAmt).divide(new BigDecimal(12),6,BigDecimal.ROUND_HALF_UP);//应还利息totalIntAmt = totalIntAmt.add(result[2]).add(result[2].setScale(2, BigDecimal.ROUND_HALF_UP).negate());result[1] = result[1].setScale(2,BigDecimal.ROUND_HALF_UP);result[2] = result[2].setScale(2,BigDecimal.ROUND_HALF_UP);if (prodPerdSum == 0) {result[2] = result[2].add(totalIntAmt.setScale(2,BigDecimal.ROUND_HALF_UP));}result[0] = result[1].add(result[2]);//月应还金额=应还本金+应还利息
            results.add(result);}return results;}/*** @description: 每月还利息,到期还本金-按天计算(5)* @creator: roilat-D* @createDate: 2016年5月24日 * @modifier:* @modifiedDate:* @param loanAmt        借款金额* @param prftRat        产品利率* @param prodPerdSum    产品期数* @return* @throws Exception*/public static List<BigDecimal[]> calcForRepayInterestPerMonthByDays(BigDecimal loanAmt, BigDecimal prftRat, int prodPerdSum, int[] daysPerMonth) throws Exception {/*** 每月还利息,到期还本金。每月的还款金额X,融资金额A,年化收益B,总期数M,,每月天数D* 每月还款本金:0,最后一个月为A* 每月还款利息:A*B/365*本期天数* X=每月还款本金+每月还款利息101*/if (daysPerMonth.length != prodPerdSum) {throw new Exception("每期的天数列表和实际期数不一致!");}List<BigDecimal[]> results = new ArrayList<BigDecimal[]>(prodPerdSum);BigDecimal totalIntAmt = new BigDecimal("0");BigDecimal[] result;int i = 0;while (prodPerdSum > i) {BigDecimal monthIntAmt = prftRat.multiply(loanAmt).multiply(new BigDecimal(daysPerMonth[i])).divide(new BigDecimal(365),6,BigDecimal.ROUND_HALF_UP);//A*dayRat*天数,应还利息result = new BigDecimal[3];if (prodPerdSum == i+1) {result[1] = loanAmt;//应还本金} else {result[1] = new BigDecimal(0);//应还本金
            }result[2] = monthIntAmt;//应还利息totalIntAmt = totalIntAmt.add(result[2]).add(result[2].setScale(2, BigDecimal.ROUND_HALF_UP).negate());result[1] = result[1].setScale(2,BigDecimal.ROUND_HALF_UP);result[2] = result[2].setScale(2,BigDecimal.ROUND_HALF_UP);if (prodPerdSum == i+1) {result[2] = result[2].add(totalIntAmt.setScale(2,BigDecimal.ROUND_HALF_UP));}result[0] = result[1].add(result[2]);//月应还金额=应还本金+应还利息
            results.add(result);i++;}return results;}/*** @description: 到期还本还息-按月份算(6)* @creator: roilat-D* @createDate: 2016年5月24日 * @modifier:* @modifiedDate:* @param loanAmt        借款金额* @param prftRat        产品利率* @param prodPerdSum    产品期数* @return* @throws Exception*/public static List<BigDecimal[]> calcForRepayOnceExpireByMonth(BigDecimal loanAmt, BigDecimal prftRat, int prodPerdSum) throws Exception {/*** 到期还本还息* 还款日还款,本金+利息*/List<BigDecimal[]> results = new ArrayList<BigDecimal[]>(prodPerdSum);BigDecimal[] result;int i = 0;while (prodPerdSum > i) {result = new BigDecimal[3];if (i == prodPerdSum-1) {result[1] = loanAmt;//应还本金result[2] = prftRat.multiply(loanAmt).multiply(new BigDecimal(prodPerdSum)).divide(new BigDecimal(12),6,BigDecimal.ROUND_HALF_UP);//应还利息:A*B*月数/12}else{result[1] = new BigDecimal(0);//应还本金result[2] = new BigDecimal(0);//应还利息
            }result[1] = result[1].setScale(2,BigDecimal.ROUND_HALF_UP);result[2] = result[2].setScale(2,BigDecimal.ROUND_HALF_UP);result[0] = result[1].add(result[2]);//月应还金额=应还本金+应还利息
            results.add(result);i++;}return results;}/*** @description: 到期还本还息-按天计算(7)* @creator: roilat-D* @createDate: 2016年5月24日 * @modifier:* @modifiedDate:* @param loanAmt        借款金额* @param prftRat        产品利率* @param prodPerdSum    产品期数* @return* @throws Exception*/public static List<BigDecimal[]> calcForRepayOnceExpireByDay(BigDecimal loanAmt, BigDecimal prftRat, int prodPerdSum, int[] daysPerMonth) throws Exception {/*** 到期还本还息* 还款日还款,本金+利息*/if (daysPerMonth.length != prodPerdSum) {throw new Exception("每期的天数列表和实际期数不一致!");}List<BigDecimal[]> results = new ArrayList<BigDecimal[]>(prodPerdSum);BigDecimal[] result;int i = 0;int totalDays = 0;while (prodPerdSum > i) {totalDays += daysPerMonth[i];result = new BigDecimal[3];if (prodPerdSum == i+1) {result[1] = loanAmt;//应还本金result[2] = prftRat.multiply(loanAmt).multiply(new BigDecimal(totalDays)).divide(new BigDecimal(365),6,BigDecimal.ROUND_HALF_UP);//年利率*总天数*本金/365=应还利息} else {result[1] = new BigDecimal(0);//应还本金result[2] = new BigDecimal(0);//应还利息
}result[1] = result[1].setScale(2,BigDecimal.ROUND_HALF_UP);result[2] = result[2].setScale(2,BigDecimal.ROUND_HALF_UP);result[0] = result[1].add(result[2]);//月应还金额=应还本金+应还利息
            results.add(result);i++;}return results;}/*** @description: 根据上线时间和期数,计划每期的天数* @creator: roilat-D* @createDate: 2016年5月24日 * @modifier:* @modifiedDate:* @param onlineDate    上线时间* @param prodPerdSum    产品总期数* @return*/public static int[] calcDaysForPerMonth(Date onlineDate, int prodPerdSum) {Calendar cal = Calendar.getInstance();cal.setTime(onlineDate);int[] result = new int[prodPerdSum];int month = cal.get(Calendar.MONTH);//获取上线月份(比实际月份小1)int i = 0;month ++;//上线日期的下个月开始while (i < prodPerdSum) {if (month == 12) {month = 0;}result[i++] = daysForPerMonthConstant[month++];}return result;}}

另一个依赖的工具方法ArithUtil.pow():

 /*** @description: BigDecimal类型的乘方运算* @creator: roilat-D* @createDate: 2016年5月24日 * @modifier:* @modifiedDate:* @param bd    底数* @param times    乘方次数* @return*/public static BigDecimal pow(BigDecimal bd, int times) throws Exception {//0、异常判断if (times > Short.MAX_VALUE) {//不能大于65535throw new Exception("乘方运算的次数太大,目前系统暂不支持!");}//1、按照二进制位将次数进行反转int temp = 0;int n = 0;//位数计数器while (times > 0) {temp = temp << 1;temp |= times & 0x01;times = times >> 1;n++;//System.out.println("" +Integer.toBinaryString(temp) + "---" +Integer.toBinaryString(times));
           }//2、乘方运算BigDecimal result = new BigDecimal(1);while (n-- > 0) {if ((temp & 0x01) == 1) {result = result.multiply(result).multiply(bd);} else {result = result.multiply(result);}temp = temp >>> 1;}return result;}

package cn.roilat.study.web.util;
import java.math.BigDecimal;import java.util.ArrayList;import java.util.Calendar;import java.util.Date;import java.util.List;
/** * javadoc for com.hansy.p2p.tool.LoanCalcUtils * @Copyright: 2016成都环赛信息技术有限公司  * @author: roilat-D * @since: 2016年5月23日 */public class LoanCalcUtils2 {
/** * BigDecimal[0]月应还金额 * BigDecimal[1]应还本金金额 * BigDecimal[2]应还利息金额 */
private static int[] daysForPerMonthConstant = {31, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30};
/** * @description: 等额本息-按月份算(1) * @creator: roilat-D * @createDate: 2016年5月23日  * @modifier: * @modifiedDate: * @param loanAmt借款金额 * @param prftRat产品利率 * @param prodPerdSum产品期数 * @return * @throws Exception  */public static List<BigDecimal[]> calcForEqualCapitalPlusInterestByMonth(BigDecimal loanAmt, BigDecimal prftRat, int prodPerdSum) throws Exception {/** * 等额本息的还款方式,每月的还款金额X,融资金额A,年化收益B,总期数M,月利率m * X=((A*B/12*(1+B/12)^m)/((1+B/12)^m-1) * 经过推导得到:(AB(12+B)^m)/(12*(12+m)^m-12^(m+1)) * 每月所还的利息:当月本金余额*B/12 * 每月所还的本金:X-每月所还的利息 */List<BigDecimal[]> results = new ArrayList<BigDecimal[]>(prodPerdSum);
BigDecimal t0 = prftRat.add(new BigDecimal(12));BigDecimal t1 = ArithUtil.pow(t0, prodPerdSum);BigDecimal fz = loanAmt.multiply(prftRat).multiply(t1);BigDecimal fm = t1.multiply(new BigDecimal(12)).add(new BigDecimal(Math.pow(12, prodPerdSum+1)).negate());BigDecimal monthRepay = fz.divide(fm,6,BigDecimal.ROUND_HALF_UP);BigDecimal totalAmt = new BigDecimal("0");System.out.println("monthRepay----" + monthRepay);BigDecimal[] result;BigDecimal surplusAmt = loanAmt;//首月的剩余额为贷款总额while (prodPerdSum-- > 0) {result = new BigDecimal[3];result[0] = monthRepay;//月应还金额result[2] = surplusAmt.multiply(prftRat).divide(new BigDecimal(12),6,BigDecimal.ROUND_HALF_UP);//应还利息=剩余金额*月利率result[0] = result[0].setScale(2,BigDecimal.ROUND_HALF_UP);//四舍五入result[2] = result[2].setScale(2,BigDecimal.ROUND_HALF_UP);//四舍五入totalAmt = totalAmt.add(monthRepay.add(result[0].negate()));//计算总金额每次四舍五入的误差(6位小数)result[1] = result[0].add(result[2].negate());surplusAmt = surplusAmt.add(result[1].negate());//剩余本金=上次剩余本金-本次应还本金(两位小数)if(prodPerdSum == 0){//最后一个月result[0] = result[0].add(totalAmt.setScale(2,BigDecimal.ROUND_HALF_UP));result[1] = result[1].add(surplusAmt);result[2] = result[2].add(surplusAmt.negate()).add(totalAmt.setScale(2,BigDecimal.ROUND_HALF_UP));}results.add(result);}return results;}
/** * @description: 等额本金-按月份算(2) * @creator: roilat-D * @createDate: 2016年5月24日  * @modifier: * @modifiedDate: * @param loanAmt借款金额 * @param prftRat产品利率 * @param prodPerdSum产品期数 * @return * @throws Exception */public static List<BigDecimal[]> calcForEqualCapitalByMonth(BigDecimal loanAmt, BigDecimal prftRat, int prodPerdSum) throws Exception {/** * 等额本金的还款方式,每月的还款金额X,融资金额A,年化收益B,总期数M * 每月还款本金:A/M * 每月还款利息:上期所剩本金*B/12 * X=每月还款本金+每月还款利息 * */List<BigDecimal[]> results = new ArrayList<BigDecimal[]>(prodPerdSum);
BigDecimal monthCapital = loanAmt.divide(new BigDecimal(prodPerdSum),6,BigDecimal.ROUND_HALF_UP);//A/M,应还本金(6位)BigDecimal totalIntAmt = new BigDecimal("0");System.out.println("monthCapital----" + monthCapital);BigDecimal[] result;BigDecimal surplusAmt = loanAmt;//首月的剩余额为贷款总额while (prodPerdSum-- > 0) {result = new BigDecimal[3];result[1] = monthCapital;//应还本金result[2] = prftRat.multiply(surplusAmt).divide(new BigDecimal(12),6,BigDecimal.ROUND_HALF_UP);//应还利息=剩余金额*月利率totalIntAmt = totalIntAmt.add(result[2].add(result[2].setScale(2, BigDecimal.ROUND_HALF_UP).negate()));//计算利息每次四舍五入的误差(6位小数)result[1] = result[1].setScale(2,BigDecimal.ROUND_HALF_UP);//四舍五入result[2] = result[2].setScale(2,BigDecimal.ROUND_HALF_UP);//四舍五入result[0] = result[1].add(result[2]);
surplusAmt = surplusAmt.add(result[1].negate());//剩余本金=上次剩余本金-本次应还本金(两位小数)if(prodPerdSum == 0){//最后一个月result[1] = result[1].add(surplusAmt.setScale(2,BigDecimal.ROUND_HALF_UP));result[2] = result[2].add(totalIntAmt.setScale(2,BigDecimal.ROUND_HALF_UP));result[0] = result[1].add(result[2]);}results.add(result);}return results;}
/** * @description: 等额本金-按天份算(3) * @creator: roilat-D * @createDate: 2016年5月24日  * @modifier: * @modifiedDate: * @param loanAmt借款金额 * @param prftRat产品利率 * @param prodPerdSum产品期数 * @param prodPerdSum每期的天数 * @return * @throws Exception */public static List<BigDecimal[]> calcForEqualCapitalByDays(BigDecimal loanAmt, BigDecimal prftRat, int prodPerdSum, int[] daysPerMonth) throws Exception {/** * 等额本金的还款方式,每天的还款金额X,融资金额A,年化收益B,总期数M,每月天数D * 每月还款本金:A/M * 每月还款利息:上期所剩本金*B/1年天数*本期天数 * X=每月还款本金+每月还款利息 * */
if (daysPerMonth.length != prodPerdSum) {throw new Exception("每期的天数列表和实际期数不一致!");}List<BigDecimal[]> results = new ArrayList<BigDecimal[]>(prodPerdSum);
BigDecimal monthCapital = loanAmt.divide(new BigDecimal(prodPerdSum),6,BigDecimal.ROUND_HALF_UP);//A/M,应还本金BigDecimal[] result;BigDecimal totalIntAmt = new BigDecimal("0");BigDecimal surplusAmt = loanAmt;//首月的剩余额为贷款总额int i = 0;while (i < prodPerdSum) {result = new BigDecimal[3];result[1] = monthCapital;//应还本金result[2] = prftRat.multiply(surplusAmt).multiply(new BigDecimal(daysPerMonth[i])).divide(new BigDecimal(365),6,BigDecimal.ROUND_HALF_UP);//应还利息=剩余金额*天利率*天数totalIntAmt = totalIntAmt.add(result[2].add(result[2].setScale(2, BigDecimal.ROUND_HALF_UP).negate()));//计算利息每次四舍五入的误差(6位小数)result[1] = result[1].setScale(2,BigDecimal.ROUND_HALF_UP);//四舍五入result[2] = result[2].setScale(2,BigDecimal.ROUND_HALF_UP);//四舍五入result[0] = result[1].add(result[2]);
surplusAmt = surplusAmt.add(result[1].negate());//剩余本金=上次剩余本金-本次应还本金(两位小数)if(prodPerdSum == i+1){//最后一个月result[1] = result[1].add(surplusAmt.setScale(2,BigDecimal.ROUND_HALF_UP));result[2] = result[2].add(totalIntAmt.setScale(2,BigDecimal.ROUND_HALF_UP));result[0] = result[1].add(result[2]);}results.add(result);i++;}return results;}
/** * @description: 每月还利息,到期还本金-按月份算(4) * @creator: roilat-D * @createDate: 2016年5月24日  * @modifier: * @modifiedDate: * @param loanAmt借款金额 * @param prftRat产品利率 * @param prodPerdSum产品期数 * @return * @throws Exception */public static List<BigDecimal[]> calcForRepayInterestPerMonthByMonth(BigDecimal loanAmt, BigDecimal prftRat, int prodPerdSum) throws Exception {/** * 每月还利息,到期还本金。每月的还款金额X,融资金额A,年化收益B,总期数M * 每月还款本金:0,最后一个月为A * 每月还款利息:A*B/12 * X=每月还款本金+每月还款利息101 */List<BigDecimal[]> results = new ArrayList<BigDecimal[]>(prodPerdSum);
BigDecimal[] result;BigDecimal totalIntAmt = new BigDecimal("0");
while (prodPerdSum-- > 0) {result = new BigDecimal[3];if (prodPerdSum == 0) {result[1] = loanAmt;//应还本金} else {result[1] = new BigDecimal(0);//应还本金}
result[2] = prftRat.multiply(loanAmt).divide(new BigDecimal(12),6,BigDecimal.ROUND_HALF_UP);//应还利息totalIntAmt = totalIntAmt.add(result[2]).add(result[2].setScale(2, BigDecimal.ROUND_HALF_UP).negate());result[1] = result[1].setScale(2,BigDecimal.ROUND_HALF_UP);result[2] = result[2].setScale(2,BigDecimal.ROUND_HALF_UP);if (prodPerdSum == 0) {result[2] = result[2].add(totalIntAmt.setScale(2,BigDecimal.ROUND_HALF_UP));}result[0] = result[1].add(result[2]);//月应还金额=应还本金+应还利息results.add(result);}return results;}
/** * @description: 每月还利息,到期还本金-按天计算(5) * @creator: roilat-D * @createDate: 2016年5月24日  * @modifier: * @modifiedDate: * @param loanAmt借款金额 * @param prftRat产品利率 * @param prodPerdSum产品期数 * @return * @throws Exception */public static List<BigDecimal[]> calcForRepayInterestPerMonthByDays(BigDecimal loanAmt, BigDecimal prftRat, int prodPerdSum, int[] daysPerMonth) throws Exception {/** * 每月还利息,到期还本金。每月的还款金额X,融资金额A,年化收益B,总期数M,,每月天数D * 每月还款本金:0,最后一个月为A * 每月还款利息:A*B/365*本期天数 * X=每月还款本金+每月还款利息101 */
if (daysPerMonth.length != prodPerdSum) {throw new Exception("每期的天数列表和实际期数不一致!");}List<BigDecimal[]> results = new ArrayList<BigDecimal[]>(prodPerdSum);
BigDecimal totalIntAmt = new BigDecimal("0");BigDecimal[] result;int i = 0;while (prodPerdSum > i) {BigDecimal monthIntAmt = prftRat.multiply(loanAmt).multiply(new BigDecimal(daysPerMonth[i])).divide(new BigDecimal(365),6,BigDecimal.ROUND_HALF_UP);//A*dayRat*天数,应还利息result = new BigDecimal[3];if (prodPerdSum == i+1) {result[1] = loanAmt;//应还本金} else {result[1] = new BigDecimal(0);//应还本金}
result[2] = monthIntAmt;//应还利息totalIntAmt = totalIntAmt.add(result[2]).add(result[2].setScale(2, BigDecimal.ROUND_HALF_UP).negate());result[1] = result[1].setScale(2,BigDecimal.ROUND_HALF_UP);result[2] = result[2].setScale(2,BigDecimal.ROUND_HALF_UP);if (prodPerdSum == i+1) {result[2] = result[2].add(totalIntAmt.setScale(2,BigDecimal.ROUND_HALF_UP));}result[0] = result[1].add(result[2]);//月应还金额=应还本金+应还利息results.add(result);i++;}return results;}
/** * @description: 到期还本还息-按月份算(6) * @creator: roilat-D * @createDate: 2016年5月24日  * @modifier: * @modifiedDate: * @param loanAmt借款金额 * @param prftRat产品利率 * @param prodPerdSum产品期数 * @return * @throws Exception */public static List<BigDecimal[]> calcForRepayOnceExpireByMonth(BigDecimal loanAmt, BigDecimal prftRat, int prodPerdSum) throws Exception {/** * 到期还本还息 * 还款日还款,本金+利息 */List<BigDecimal[]> results = new ArrayList<BigDecimal[]>(prodPerdSum);
BigDecimal[] result;int i = 0;while (prodPerdSum > i) {result = new BigDecimal[3];if (i == prodPerdSum-1) {result[1] = loanAmt;//应还本金result[2] = prftRat.multiply(loanAmt).multiply(new BigDecimal(prodPerdSum)).divide(new BigDecimal(12),6,BigDecimal.ROUND_HALF_UP);//应还利息:A*B*月数/12}else{result[1] = new BigDecimal(0);//应还本金result[2] = new BigDecimal(0);//应还利息}result[1] = result[1].setScale(2,BigDecimal.ROUND_HALF_UP);result[2] = result[2].setScale(2,BigDecimal.ROUND_HALF_UP);result[0] = result[1].add(result[2]);//月应还金额=应还本金+应还利息results.add(result);i++;}return results;}
/** * @description: 到期还本还息-按天计算(7) * @creator: roilat-D * @createDate: 2016年5月24日  * @modifier: * @modifiedDate: * @param loanAmt借款金额 * @param prftRat产品利率 * @param prodPerdSum产品期数 * @return * @throws Exception */public static List<BigDecimal[]> calcForRepayOnceExpireByDay(BigDecimal loanAmt, BigDecimal prftRat, int prodPerdSum, int[] daysPerMonth) throws Exception {/** * 到期还本还息 * 还款日还款,本金+利息 */if (daysPerMonth.length != prodPerdSum) {throw new Exception("每期的天数列表和实际期数不一致!");}
List<BigDecimal[]> results = new ArrayList<BigDecimal[]>(prodPerdSum);
BigDecimal[] result;int i = 0;int totalDays = 0;while (prodPerdSum > i) {totalDays += daysPerMonth[i];result = new BigDecimal[3];if (prodPerdSum == i+1) {result[1] = loanAmt;//应还本金result[2] = prftRat.multiply(loanAmt).multiply(new BigDecimal(totalDays)).divide(new BigDecimal(365),6,BigDecimal.ROUND_HALF_UP);//年利率*总天数*本金/365=应还利息} else {result[1] = new BigDecimal(0);//应还本金result[2] = new BigDecimal(0);//应还利息
}result[1] = result[1].setScale(2,BigDecimal.ROUND_HALF_UP);result[2] = result[2].setScale(2,BigDecimal.ROUND_HALF_UP);result[0] = result[1].add(result[2]);//月应还金额=应还本金+应还利息results.add(result);i++;}return results;}
/** * @description: 根据上线时间和期数,计划每期的天数 * @creator: roilat-D * @createDate: 2016年5月24日  * @modifier: * @modifiedDate: * @param onlineDate上线时间 * @param prodPerdSum产品总期数 * @return */public static int[] calcDaysForPerMonth(Date onlineDate, int prodPerdSum) {Calendar cal = Calendar.getInstance();cal.setTime(onlineDate);int[] result = new int[prodPerdSum];int month = cal.get(Calendar.MONTH);//获取上线月份(比实际月份小1)int i = 0;month ++;//上线日期的下个月开始while (i < prodPerdSum) {if (month == 12) {month = 0;}result[i++] = daysForPerMonthConstant[month++];}return result;}

public static void main(String[] args) throws Exception {List<BigDecimal[]> list = LoanCalcUtils2.calcForEqualCapitalByMonth(new BigDecimal("10000"), new BigDecimal("0.10"), 12);BigDecimal sum = new BigDecimal(0);for(BigDecimal[] decimals:list){sum = sum.add(decimals[2]);}System.out.println(sum);}}

转载于:https://www.cnblogs.com/roilat/p/10753534.html

等额本金,等额本息,分期付息到期还本,到期还本还息计算实现相关推荐

  1. 等额本金等额本息工具类2023

    等额本金&等额本息工具类2023 等额本金 等额本金 问题反馈 等额本金 import java.math.BigDecimal; import java.math.RoundingMode; ...

  2. java 等额本金等额本息工具类

    2019独角兽企业重金招聘Python工程师标准>>> 等额本息: /*** Description:等额本息工具类* Copyright: Copyright (corporati ...

  3. 如何使用python进行等额本金-等额本息贷款计算

    #贷款额为a,月利率为i,年利率为I,还款月数为n a = 500000.00 I = 0.11495 i = I/12 n = 60 print("-----等额本息计算,以5个月为例-- ...

  4. 银行业务中贷款算法等额本金等额本息算法程序

    写一个贷款计算器,从网上找了一个算法,自己改了改可以用了,不错,分享给大家 import java.text.DecimalFormat; public class jshk { public sta ...

  5. 等额本金.等额本息.房贷计算

    <?phpfunction debx(){$dkm = 12; //贷款月数,20年就是240个月$dkTotal = 2000; //贷款总额$dknl = 0.049; //贷款年利率$em ...

  6. 房贷利率有无套路?Python解读“等额本金与等额本息”的差异所在

    作者 | xiaoyu 来源 | Python数据科学 很多朋友留言说不知道房贷利率的不同归还方式是不是有套路,内心深表疑虑.我的第一反应是因为房贷很高,大家看到消费分期的套路自然而然就想到了房贷,很 ...

  7. python等额本息和等额本金_用Python解读房贷利率,要不要看随你

    可能很多买过房.贷过款的朋友大概都知道怎么回事,但是我相信大部分人也没细研究过,而绝大部分人买房时更是任由房屋中介摆布,因为给了中介费相信他们可以算的明明白白,自己也就不过多深究了.但我觉得买房不是小 ...

  8. Java Swing写简单计算器以及拓展贷款计算器(等额本息和等额本金计算可以单独拿出来用)

    1. 简单计算器 纯手写 package com.jisuanqi;import com.sun.xml.internal.ws.util.StringUtils;import javax.swing ...

  9. 等额本金VS等额本息

    升息尚无定论 个人房贷市场已现不小波澜 ? http://www.soufun.com 房地产门户-搜房 2004-08-17 11:13:00.0? ? 地产资讯播报:http://news.sh. ...

最新文章

  1. 光流 Motion Estimation
  2. 每日一皮:据说PM就是这样忍受你的!
  3. Spring+Quartz实现定时任务
  4. gulp中使用babel-polyfill编译es6拓展语法
  5. delphi 7 学习步骤
  6. linux没有那个文件或目录_Linux安装python faiss模块
  7. license是什么_云数据库时代,AWS凭什么执牛耳?
  8. Geotrellis系列文章链接
  9. php 正则表达式 匹配 字符串,PHP 字符串与正则表达式匹配
  10. 搭建petalinux开发环境
  11. Android为什么图片模糊不清,Android打开图库中图片为什么从模糊变清晰
  12. 2014年全国高等学校名单
  13. 计算机与网络技术 英语,计算机与网络英语词汇(S3)
  14. 『拼多多』产品体验报告
  15. android 身份认证技术,Android平台上基于人脸识别的身份认证系统的设计与实现
  16. 你们有半数以上的人留下的是gmail而不是QQMail/Foxmail的电子邮件
  17. 浏览器缓存Cache
  18. matlab雷达目标回波仿真
  19. springboot启动错误 Could not resolve placeholder
  20. 无监督 自监督---综述

热门文章

  1. QT 生成exe图标
  2. Jquery点击事件连续执行多次
  3. Python-Mac 怎么下载Easygui
  4. 区块链报告会心得体会3000_2019年听讲座心得体会3000字范例汇编三篇
  5. 项目经理 你为什么应聘这个职位
  6. 屏幕之间的空白:跨屏时代即将到来
  7. Dom4j 解析 XML
  8. Java基础知识强化之网络编程笔记03:UDP之UDP协议发送数据 和 接收数据
  9. 【逻辑漏洞技巧拓展】————4、逻辑漏洞之支付漏洞
  10. 用Python绘制多个同心圆