我正在研究抵押贷款计算公式,我从Math.pow()获得了不同的结果,我不知道为什么。
以下是测试设置:
double interestRatePercent = 7;
double monthlyInterestRate = (interestRatePercent / 100) / MONTHS_PER_YEAR;
int numberOfPayments = loanTermInYears * MONTHS_PER_YEAR;
Log.i(TAG, String.format("monthlyInterestRate: %f", monthlyInterestRate));
Log.i(TAG, String.format("numberOfPayments: %d", numberOfPayments));
Log.i(TAG, " ");
Log.i(TAG, "Hardcoded result:");
double hardcodedResult = Math.pow(1.0 + 0.005833, numberOfPayments);
Log.i(TAG, String.format("(1 + 0.005833)^360 = %f", hardcodedResult));
Log.i(TAG, " ");
Log.i(TAG, "Parameterized result:");
double paramResult = Math.pow(1.0 + monthlyInterestRate, numberOfPayments);
Log.i(TAG, String.format("(1 + %f)^%d = %f", monthlyInterestRate, numberOfPayments, paramResult));
Log.i(TAG, " ");
Log.i(TAG, "BigDecimal result:");
BigDecimal bigResult = BigDecimal.valueOf(1.0 + monthlyInterestRate);
bigResult = bigResult.pow(numberOfPayments);
Log.i(TAG, String.format("(1 + %f)^%d = %f", monthlyInterestRate, numberOfPayments, bigResult));
Log.i(TAG, " ");
Log.i(TAG, " ");
以下是测试结果:
monthlyInterestRate: 0.005833
numberOfPayments: 360
Hardcoded result:
(1 + 0.005833)^360 = 8.115529
Parameterized result:
(1 + 0.005833)^360 = 8.116497
BigDecimal result:
(1 + 0.005833)^360 = 8.116497
只有硬编码的结果才是正确的。 Math.pow和BigDecimal.pow结果都很糟糕。
有什么想法吗?
答案 0 :(得分:6)
7/100/12约为0.00583333333,而不是0.005833。使用%f时,默认情况下只能看到小数点后的6位数。
答案 1 :(得分:3)
BigDecimal bigResult = BigDecimal.valueOf(1.0 + monthlyInterestRate);
当您创建BigDecimal时,您将失去精确度,因为1.0 + monthlyInterestRate
将失去精确度。要获得更好的精确度,请为1.0创建BigDecimal
,然后使用add()
方法将其添加到值为0.005833的另一个BigDecimal
。然后使用BigDecimal
pow()
函数。
换句话说,从更简单的BigDecimal
而不是BigDecimals
或int
类型构建double
。
答案 2 :(得分:1)
差异是由于在硬编码结果计算中舍入0.002533333333333333599324266316443754476495087146759033203125(monthlyInterestRate的实际值)为0.005833。为方便起见,我修改了程序以使用System.out.println。我更改了monthlyInterestRate的输出以准确打印它,然后在硬编码计算中使用该值。输出是:
monthlyInterestRate: 0.005833333333333333599324266316443754476495087146759033203125
numberOfPayments: 360
Hardcoded result:
(1 + 0.005833333333333333599324266316443754476495087146759033203125)^360 = 8.116497
Parameterized result:
(1 + 0.005833)^360 = 8.116497
BigDecimal result:
(1 + 0.005833)^360 = 8.116497
以下是修改后的程序:
import java.math.BigDecimal;
public class Test {
public static void main(String[] args) {
double interestRatePercent = 7;
int MONTHS_PER_YEAR = 12;
int loanTermInYears = 30;
double monthlyInterestRate = (interestRatePercent / 100)
/ MONTHS_PER_YEAR;
int numberOfPayments = loanTermInYears * MONTHS_PER_YEAR;
// System.out.println(String.format("monthlyInterestRate: %f",
// monthlyInterestRate));
System.out.println("monthlyInterestRate: "
+ new BigDecimal(monthlyInterestRate));
System.out.println(String.format("numberOfPayments: %d",
numberOfPayments));
System.out.println(" ");
System.out.println("Hardcoded result:");
double hardcodedResult = Math
.pow(1.0 + 0.005833333333333333599324266316443754476495087146759033203125,
numberOfPayments);
System.out
.println(String
.format("(1 + 0.005833333333333333599324266316443754476495087146759033203125)^360 = %f",
hardcodedResult));
System.out.println(" ");
System.out.println("Parameterized result:");
double paramResult = Math.pow(1.0 + monthlyInterestRate,
numberOfPayments);
System.out.println(String.format("(1 + %f)^%d = %f",
monthlyInterestRate, numberOfPayments, paramResult));
System.out.println(" ");
System.out.println("BigDecimal result:");
BigDecimal bigResult = BigDecimal.valueOf(1.0 + monthlyInterestRate);
bigResult = bigResult.pow(numberOfPayments);
System.out.println(String.format("(1 + %f)^%d = %f",
monthlyInterestRate, numberOfPayments, bigResult));
System.out.println(" ");
System.out.println(" ");
}
}