这个问题在这里已经有了答案:
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/