Reputation: 3699
I am working with the Math.pow() function, and have the following code:
double monthlyRate = (0.7d / 12);
int loanLength = 3;
double powerTest = Math.pow(1.00583, 36);
double powerResult = Math.pow((1 + monthlyRate),(loanLength * 12));
When this is run through the debugger, the values become
powerTest => 1.2327785029794363
powerResult => 7.698552870922063
The first is the correct one. I've stepped into the Math.pow function on both of the assignment lines. For powerTest, the parameters for Math.pow are double a => 1.00583 double b => 36.0
For powerResult, they are double a => 1.0058333333333333 double b => 36.0
I know that this is an issue with the way floating point math is performed by the machine, I'm just not sure how to correct it. I tried doing the following before the calculation with poor results:
monthlyRate = Math.round(monthlyRate * 1000) / 1000;
Upvotes: 0
Views: 4460
Reputation: 32923
On Java you can use BigDecimal to perform money operations resulting on accurate numbers: it is the Sun/Oracle recommended way to store money numbers.
// I'm using Strings for most accuracy
BigDecimal monthlyRate = new BigDecimal("0.7").divide(new BigDecimal(12));
int loanLength = 3;
BigDecimal powerTest = new BigDecimal("1.00583").pow(36);
BigDecimal powerResult = BigDecimal.ONE.add(monthlyRate).pow(loanLength * 12);
Upvotes: 1
Reputation: 22596
Obviously a such big difference in the resut(1.23... and 7.70) is not related to the way floats are coded but more than you made a mistake somewhere 1+0.7/12 = 1.0583 is different from 1.00583 ;-).
Upvotes: 2
Reputation: 3611
Your expression 0.7d/12 = 0.0583, in the powerTest expression you are using 0.00583.
Upvotes: 3
Reputation: 77024
I think part of the problem is that 0.7/12 ~ 0.058333
, and 1.0583 > 1.00583
. My bet is this is the true source of your discrepancy, the floating point adjustments have little to do with it.
Upvotes: 2
Reputation: 67986
Math.round(monthlyRate * 1000) / 1000.0;
You were using integer division.
Upvotes: 1