这是我的尝试,主要是尝试使其具有与Excel相同的参数。 我从Apache POI删除了代码,并将其切换为使用BigDecimal 。
/**
* 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 FincanceLib
*/
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)
);
}