我正在处理一个抵押贷款计算公式,并且得到了与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的结果都很糟糕。
有什么想法吗?
发布于 2014-02-02 14:08:02
BigDecimal bigResult = BigDecimal.valueOf(1.0 + monthlyInterestRate);
当您创建BigDecimal时,您将失去精度,因为1.0 + monthlyInterestRate
将失去精度。要获得更高的精度,请为1.0创建一个BigDecimal
,然后使用add()
方法将其添加到值为0.005833的另一个BigDecimal
中。然后使用BigDecimal
pow()
函数。
换句话说,从更简单的BigDecimal
类型(而不是int
或double
类型)构建int
。
发布于 2014-02-02 14:05:18
7/100/12大约是0.00583333333,而不是0.005833。使用%f时,默认情况下,在小数点之后只看到6位数字。
发布于 2014-02-02 14:19:17
这一差异是由于0.005833333333333333599324266316443754476495087146759033203125,舍入了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(" ");
}
}
https://stackoverflow.com/questions/21516811
复制