6

我敢说 Fortran 和 C++ 计算的数值会更相似。但是,根据我的经验,计算出的数字在小数位数太少后开始发散。在将一些遗留代码从前一种语言移植到后者的过程中,我遇到了这个问题。原始的 Fortran 77 代码...

  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

...输出0.842201471328735,而它的 C++ 等效...

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);

...返回0.842201286195064。也就是说,计算值仅等于小数点后六位。虽然不是 Fortran 的特别拥护者,但我倾向于认为它的结果是“正确”的,因为它在数字处理器方面享有盛誉。但是,我对计算值之间存在这种差异的原因很感兴趣。有谁知道造成这种差异的原因是什么?

4

1 回答 1

11

在 Fortran 中,默认情况下,浮点文字是单精度的,而在 C/C++ 中它们是双精度的。

因此,在您的 Fortran 代码中,计算 NUMERATOR 的表达式以单精度完成;仅在将最终结果分配给 NUMERATOR 变量时才将其转换为双精度。

计算分配给 DENOMINATOR 变量的值的表达式也是如此。

于 2010-05-03T10:46:22.867 回答