Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Discrepancy between the values computed by Fortran and C++

I would have dared say that the numeric values computed by Fortran and C++ would be way more similar. However, from what I am experiencing, it turns out that the calculated numbers start to diverge after too few decimal digits. I have come across this problem during the process of porting some legacy code from the former language to the latter. The original Fortran 77 code...

  INTEGER M, ROUND
  DOUBLE PRECISION NUMERATOR, DENOMINATOR

  M = 2
  ROUND = 1
  NUMERATOR=5./((M-1+(1.3**M))**1.8)
  DENOMINATOR = 0.7714+0.2286*(ROUND**3.82)
  WRITE (*, '(F20.15)') NUMERATOR/DENOMINATOR
  STOP

... outputs 0.842201471328735, while its C++ equivalent...

int m = 2;
int round = 1;
long double numerator = 5.0 / pow((m-1)+pow(1.3, m), 1.8);
long double denominator = 0.7714 + 0.2286 * pow(round, 3.82);
std::cout << std::setiosflags(std::ios::fixed) << std::setprecision(15)
          << numerator/denominator << std::endl;
exit(1);

... returns 0.842201286195064. That is, the computed values are equal only up to the sixth decimal. Although not particularly a Fortran advocator, I feel inclined to consider its results as the 'correct' ones, given its legitimate reputation of number cruncher. However, I am intrigued about the cause of this difference between the computed values. Does anyone know what the reason for this discrepancy could be?

like image 458
plok Avatar asked May 03 '10 10:05

plok


1 Answers

In Fortran, by default, floating point literals are single precision, whereas in C/C++ they are double precision.

Thus, in your Fortran code, the expression for calculating NUMERATOR is done in single precision; it is only converted to double precision when assigning the final result to the NUMERATOR variable.

And the same thing for the expression calculating the value that is assigned to the DENOMINATOR variable.

like image 125
janneb Avatar answered Nov 16 '22 18:11

janneb