我想用Java实现PMT功能(来自Excel)。 PMT功能的公式是:
(D7*D9/12)/(1-(1+D9/12)^(-(D11/12)*12))
其中:
例如
D7 = $1,00,000,
D9 = 10%,
D11 = 36
此处PMT功能的输出即每月付款将为$3,226.72
请有人帮我用Java计算这个函数值。
答案 0 :(得分:10)
您可以使用Apache POI:
http://poi.apache.org/apidocs/org/apache/poi/ss/formula/functions/FinanceLib.html
它节省了我的一天:D
用法示例:
FinanceLib.pmt(0.00740260861, 180, -984698, 0, false)
参数:rate
,months
,present value
,future value
,at the beginning of the period
(或最后)
答案 1 :(得分:1)
假设所有变量为double类型:
result=(d7*d9/12)/Math.pow((1-(1+D9/12),(-(d11/12)*12)))
答案 2 :(得分:0)
//D7:Finance Amount
//D9 = Rate(the rate here is annual rate)
//D11 = Term
fv=D7 * Math.pow((1 + D9/12), D11);
PMT=(fv * D9/12) / (pow((1 + D9/12), D11) - 1);
答案 3 :(得分:0)
这是JAVA中的Excel PMT等价物:
public BigDecimal calcEMI(BigDecimal P, BigDecimal N, BigDecimal ROI) {
if(BigDecimalUtil.anyOneZeroOrNull(P,N,ROI)){
SCBSUtils.throwSmartCBSException("Invalid data for calculating EMI %s, %s %s", P,N,ROI);
}
MathContext mc = MathContext.DECIMAL128;
//Excel equivalent formula == P*R*POWER(1+R,N)/(POWER(1+R,N)-1)
BigDecimal R = ROI.divide(new BigDecimal(1200),mc);
BigDecimal nemi1 = P.multiply(R,mc);
BigDecimal npower1 = (BigDecimal.ONE.add(R)).pow(N.intValue(),mc);
BigDecimal dpower1 = (BigDecimal.ONE.add(R)).pow(N.intValue(),mc);
BigDecimal denominator = dpower1.subtract(BigDecimal.ONE);
BigDecimal numerator = nemi1.multiply(npower1);
BigDecimal emi = numerator.divide(denominator,0,RoundingMode.UP);
return emi;
}
答案 4 :(得分:0)
这样的事情:
public static void main(String[] args) {
MathContext MATH_CONTEXT = new MathContext(18, RoundingMode.HALF_UP);
BigDecimal pmt = pmt(new BigDecimal("-100000", MATH_CONTEXT),
new BigDecimal("10", MATH_CONTEXT),
new BigInteger("36"));
}
public static BigDecimal pmt(BigDecimal D7, BigDecimal D9, BigInteger D11) {
BigDecimal rate = D9
.divide(new BigDecimal("100"), MATH_CONTEXT)
.divide(new BigDecimal("12"), MATH_CONTEXT);
return rate.negate(MATH_CONTEXT)
.multiply(D7.multiply(pow(BigDecimal.ONE.add(rate), D11), MATH_CONTEXT))
.divide(pow(BigDecimal.ONE.add(rate), D11).subtract(BigDecimal.ONE), MATH_CONTEXT);
}
private static BigDecimal pow(BigDecimal x, BigInteger n) {
return x.pow(n.intValue(), MATH_CONTEXT);
}
答案 5 :(得分:0)
Excel PMT功能使用比例法计算年金。现在很多人都使用Conformal方法,而年金则略低一些。
JAVA中的PMT实施:
private static double calculateAnnuity(double creditAmmount, double interestRate, double numberOfYears, int calculationPeriod) {
double annuitiesPerYear = 12.0 / (numberOfYears * 12.0) * (numberOfYears * 12.0) / calculationPeriod;
double period = 1 / annuitiesPerYear;
double interest = Math.pow(1 + (interestRate / 100), period) - 1;
double decursiveFactor = 1 + interest;
double annuityCalc = (Math.pow(decursiveFactor, numberOfYears * 12) * (decursiveFactor - 1)) / (Math.pow(decursiveFactor, numberOfYears * 12) - 1);
return Math.round((creditAmmount * annuityCalc) * 100.0) / 100.0;
}
// Test - credit ammount: 10000, interest rate 8.0 %, tenor: 60 months, .
public static void main(String [] args){
System.out.println(calculateAnnuity(10000, 8.0, 60/12.0, 1));
}
答案 6 :(得分:0)
到目前为止,所有其他答案都没有真正与Excel的结果相符。
这对我有用:
if (D9 < 1E-6) {
return (D7 / D11);
}
return (D7*D9) / (1.0 - Math.pow(1 + D9, -D11));
答案 7 :(得分:0)
这是我的尝试,主要是尝试使其与Excel具有相同的参数。我从Apache POI删除了代码,并切换为使用BigDecimal
s。
/**
* PMT function ported from Excel to Java to use BigDecimals.
* @param interestRate interest rate for the loan.
* @param numberOfPayments is the total number of payments for the loan.
* @param principal is the present value; also known as the principal.
* @param futureValue It is the future value, or the balance that you want to have left after the last payment. If fv is omitted, the fv is assumed to be zero.
* @param paymentsDueAtBeginningOfPeriod payments are due at the beginning of the period.
* @return payment
* @see <a href="https://apache.googlesource.com/poi/+/4d81d34d5d566cb22f21999e653a5829cc678ed5/src/java/org/apache/poi/ss/formula/functions/FinanceLib.java#143">FincanceLib</a>
*/
public static BigDecimal pmt(BigDecimal interestRate,
int numberOfPayments,
BigDecimal principal,
BigDecimal futureValue,
boolean paymentsDueAtBeginningOfPeriod) {
final BigDecimal n = new BigDecimal(numberOfPayments);
if (BigDecimal.ZERO.equals(interestRate)) {
return (futureValue.add(principal)).divide(n, MathContext.DECIMAL128).negate();
} else {
final BigDecimal r1 = interestRate.add(BigDecimal.ONE);
final BigDecimal pow = r1.pow(numberOfPayments);
final BigDecimal divisor;
if (paymentsDueAtBeginningOfPeriod) {
divisor = r1.multiply(BigDecimal.ONE.subtract(pow));
} else {
divisor = BigDecimal.ONE.subtract(pow);
}
return (principal.multiply(pow).add(futureValue)).multiply(interestRate).divide(divisor, MathContext.DECIMAL128);
}
}
由于小数点相应地四舍五入,您可能会遇到问题。
@Test
public void testPMT() {
assertEquals(
new BigDecimal("-3756.00"),
pmt(
new BigDecimal("0.0075000"),
36,
new BigDecimal("119000.00"),
BigDecimal.ZERO,
true
).setScale(2, RoundingMode.HALF_UP)
);
}
答案 8 :(得分:0)
Apache POI
具有用于此目的的方法,但是它在double
上运行,这对于使用money
的用例而言并不是最佳选择。
public static BigDecimal pmt(BigDecimal rate, Integer months, BigDecimal presentValue, boolean t) {
BigDecimal result = BigDecimal.ZERO;
if (rate.compareTo(BigDecimal.ZERO) == 0) {
result = new BigDecimal("-1.0").multiply(presentValue).divide(new BigDecimal(months), RoundingMode.HALF_UP);
} else {
BigDecimal r1 = rate.add(BigDecimal.ONE);
BigDecimal opt = t ? r1 : BigDecimal.ONE;
result = presentValue.multiply(r1.pow(months)).multiply(rate)
.divide( opt.multiply(BigDecimal.ONE.subtract(r1.pow(months))), RoundingMode.HALF_UP);
}
return result;
}
例如,调用它:
BigDecimal testPMT = pmt(new BigDecimal("0.002675"), 25, new BigDecial("300000"), false);
结果:-12421.758816(...)
-与使用=PMT((0.002675),25,300000)
的excel相同
现在,您可以根据需要舍入结果。
例如这样的
BigDecimal roundedPMT = testPMT.setScale(2, RoundingMode.HALF_UP);
答案 9 :(得分:0)
我尝试了上述所有公式,但都没有给出准确的结果。所以在实际公式的帮助下找到了解决方案
EMI = [P x R x (1+R)^N]/[(1+R)^N-1]
哪里 EMI 是等价的每月分期付款 P 是本金或作为贷款借入的金额 R是对贷款金额征收的利率(利率应该是月利率) N是还款期或每月分期付款的次数(期限应以月为单位)
对于下面的java代码
double loanAmt = 100000;
double roi = 9.65;
int timePeriod = 60;
double emi = (loanAmt * (roi/12)/100 * Math.pow((1+(roi/12)/100),timePeriod))/(Math.pow(1+(roi/12)/100, timePeriod)-1);
EMI 为 2107.52