-1

I have found a simple floating point error and I was wondering if there is a way around it. I'm compiling in Haiku OS. I'm in Haiku r1 Alpha 4

#include <iostream>
#include <cmath>

float P(float PV, float r, int t){
  return(r * PV/1-pow((1+r),-t));
}

int main(void){
  float PV = 100000;
  float r = .005;
  int t = 350;

  std::cout << "A loan valued at $" << PV << " at a rate of %" << r << " with a payment period of " << t << "months would be $" << P(PV,r,t) << ", per-payment.\n";

  return 0;
}

When I run it P(PV,r,t) comes out as 499.834 it should be 500. Though if I set r = 0.06 P is correct and comes out as P = 6000.

Maybe it's a compiler error. I'm using gcc version 2.95.3-haiku-121101.

phuclv
  • 37,963
  • 15
  • 156
  • 475
Whitequill Riclo
  • 788
  • 2
  • 8
  • 19
  • 5
    Read [Is floating point math broken?](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) -- and then at least use `double`. For monetary calculations, the only correct way is *fixed point math* (use integers, define where your decimal point should be) –  Jul 25 '18 at 09:37
  • it comes out with the same output `499.834`, when I use `double P(float PV, float r, int t)`. – Whitequill Riclo Jul 25 '18 at 09:43
  • 5
    `PV/1` looks really really odd. Why do you divide through `1`? It does not alter the result. – mch Jul 25 '18 at 09:43
  • @WhitequillRiclo, They meant to make it a double *before* losing accuracy from the calculation due to the more limited precision of float. I'd bet on the incorrect formula implementation before precision, though. – chris Jul 25 '18 at 09:45
  • @mch: it's the formula for a loan payment: http://financeformulas.net/Loan_Payment_Formula.html – Whitequill Riclo Jul 25 '18 at 09:46
  • 3
    you're getting the formula incorrectly. It should be `r * PV/(1 - pow(1 + r, -t))`. Remember subtraction has lower precedence than division – phuclv Jul 25 '18 at 09:47
  • 1
    Should it be `(r * PV/(1-pow((1+r),-t)))`?.By adding more braces can clarify the computation order. – KenyKeny Jul 25 '18 at 09:51
  • 1
    The result should not be `500`, it should be `605.72`, accourding to the calculator at your link. When I add the missing parantheses, I get `605.718` as result. – mch Jul 25 '18 at 09:53
  • I voted for duplicate before realizing the expression was also wrongly paranthesized. Anyways, doing this type of calculations in floating-point **is** a problem and the other one seems to be answered in comments.... –  Jul 25 '18 at 09:59
  • Don't even bother thinking about compiler bugs at this level. The chances that you're going to find one is just way to low. – eesiraed Jul 25 '18 at 16:54

1 Answers1

1

The code:

return(r * PV/1-pow((1+r),-t));

should be:

return(r * PV/(1-pow((1+r),-t)));

and the expected result is about 605.718, not 500.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312