c++ - float 学精度,c++ vs fortran

标签 c++ fortran

这个问题在这里已经有了答案:





Different precision in C++ and Fortran

(2 个回答)


去年关闭。




我试图在 C++ 和 Fortran 中实现一个递归函数,它计算第 n 个勒让德多项式在 x 处的值。在 Fortran 中,我有

recursive function legendre(n, x) result(p)
  integer, intent(in) :: n
  real(8), intent(in) :: x
  real(8) :: p

  if(n == 0) then
    p = 1.0
  else if (n == 1) then
    p = x
  else
    p = (2.0*real(n,dp)-1.0)*x*legendre(n-1,x)-(real(n,dp)-1.0)*legendre(n-2,x)
    p = p / real(n,dp)
  end if 
end function legendre

然后在 C++ 中我有
double legendre(int n, double x) {
  double p;
  if(n == 0) return 1.0;
  else if(n == 1) return x;
  else {
    p = (2.0*(double)n - 1.0)*x*legendre(n-1,x)-((double)n - 1.0)*legendre(n-2,x);
    p /= (double)n;
    return p;
  }
}

这两个函数对我来说似乎完全一样,都使用 double ,但是 Fortran 函数的结果与 C++ 的结果有很大不同。例如,
根据 WolframAlpha,legendre(7,-0.2345) = 0.28876207107499049178814404296875。上面的两个代码,在没有优化的情况下编译时会产生

Fortran:0.28876206852410113

C++:0.28876207107499052285

我知道由于浮点运算,答案不应该相同,但是这里的 double 值差异对我来说似乎有些大。 Fortran 值与其他两个值相差这么远的原因是什么?

最佳答案

尽管您的 FORTRAN 中的变量函数被定义为 double (8 字节),您指定的常量是默认(单精度,4 字节)值。

根据 this discussion ,这意味着算术以单精度精度执行:

Even if the variable that you are assigning the result to is defined to be DP, the Fortran standard requires that the arithmetic on the constants be performed using SP. That is because you are using default real constants, since you do not have any kind type parameter at the end of the constants. By rule, default real is SP.



并且,在同一个讨论中进一步:

...Starting with Fortran 90, published in June 1991, this practice of "promoting" SP constants to DP is prohibited.



因此,为了强制使用 double 数学,请将常量指定为 DP:而不是例如 1.0 , 指定 1.0D0 (对其他人也是如此)。

关于c++ - float 学精度,c++ vs fortran,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60403546/

相关文章:

python - 不完整的 gamma 函数 : can this code get any faster in cython, C 或 Fortran?

excel - 如何将我的 fortran 输出转换为 excel?

c++ - fatal error LNK1169

arrays - Fortran 错误 # 6366 : The shapes of the array expressions do not conform

compiler-errors - 即使使用 `dacosd_`,gfortran 也会给出对 `-dec-math` 的 undefined reference

c++ - 防止数组从 *[N] 衰减到 **

c++ - 如何合并同一进程多次运行的 Valgrind memcheck 报告?

c++ - 如何在使用字符串指针变量作为输入参数的函数中使用字符串值作为参数

c++ - Visual Studio 2017 中的 Intellisense 可以建议包含 C++ header 吗?

c++ - 如何在 ROS Indigo 下正确链接 opencv3(使用 CMake)?