Fortran 中的乘法与 ifort 和 gfortran 给出不同的结果
Multiplication in Fortran giving different results with ifort and gfortran
我有一个程序可以在 Linux 上使用 gfortran-9 编译,也可以在 Windows 上使用 ifort 编译。 windows 汇编是一种黑匣子,我没有多少访问权限。
无论如何,在某些时候,两个代码都必须执行相同的乘法运算,但结果在小数点后第 13 位不同。
这是我为在我的 Linux 机器上测试这个乘法而编写的测试代码:
implicit none
double precision:: a,b,c,d
200 format(F35.20)
b=20.17865682672815452747d0
c=3.75000000000000000000d0
d=32.17399999999999948841d0
a=b*c*d
write(*,200)a
end program
在 Linux 上使用 gfortran 我有 2434.60539278681835639873 值。在 Windows 上使用 ifort 完成相同的乘法并给出 2434.60539278681881114608 。两者都使用 -O2 选项编译。
我想不出不同的原因。是不是因为双精度不能更精确,我应该移动到 real(16)
?
感谢您的见解。
乘法有 3 种不同的排序方式。 gfortran和ifort恰好选择了不同的顺序。使用括号你可以看到发生了什么:
ian@eris:~/work/stack$ cat mult.f90
implicit none
double precision:: a,b,c,d
200 format(F35.20)
b=20.17865682672815452747d0
c=3.75000000000000000000d0
d=32.17399999999999948841d0
a=(b*c)*d
write(*,200)a
b=20.17865682672815452747d0
c=3.75000000000000000000d0
d=32.17399999999999948841d0
a=b*(c*d)
write(*,200)a
b=20.17865682672815452747d0
c=3.75000000000000000000d0
d=32.17399999999999948841d0
a=c*(b*d)
write(*,200)a
end program
ian@eris:~/work/stack$ gfortran --version
GNU Fortran (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ian@eris:~/work/stack$ gfortran -O2 mult.f90
ian@eris:~/work/stack$ ./a.out
2434.60539278681835639873
2434.60539278681881114608
2434.60539278681881114608
两个答案都完全正确 - 您只是看到了浮点数学的影响之一。
我有一个程序可以在 Linux 上使用 gfortran-9 编译,也可以在 Windows 上使用 ifort 编译。 windows 汇编是一种黑匣子,我没有多少访问权限。
无论如何,在某些时候,两个代码都必须执行相同的乘法运算,但结果在小数点后第 13 位不同。
这是我为在我的 Linux 机器上测试这个乘法而编写的测试代码:
implicit none
double precision:: a,b,c,d
200 format(F35.20)
b=20.17865682672815452747d0
c=3.75000000000000000000d0
d=32.17399999999999948841d0
a=b*c*d
write(*,200)a
end program
在 Linux 上使用 gfortran 我有 2434.60539278681835639873 值。在 Windows 上使用 ifort 完成相同的乘法并给出 2434.60539278681881114608 。两者都使用 -O2 选项编译。
我想不出不同的原因。是不是因为双精度不能更精确,我应该移动到 real(16)
?
感谢您的见解。
乘法有 3 种不同的排序方式。 gfortran和ifort恰好选择了不同的顺序。使用括号你可以看到发生了什么:
ian@eris:~/work/stack$ cat mult.f90
implicit none
double precision:: a,b,c,d
200 format(F35.20)
b=20.17865682672815452747d0
c=3.75000000000000000000d0
d=32.17399999999999948841d0
a=(b*c)*d
write(*,200)a
b=20.17865682672815452747d0
c=3.75000000000000000000d0
d=32.17399999999999948841d0
a=b*(c*d)
write(*,200)a
b=20.17865682672815452747d0
c=3.75000000000000000000d0
d=32.17399999999999948841d0
a=c*(b*d)
write(*,200)a
end program
ian@eris:~/work/stack$ gfortran --version
GNU Fortran (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
ian@eris:~/work/stack$ gfortran -O2 mult.f90
ian@eris:~/work/stack$ ./a.out
2434.60539278681835639873
2434.60539278681881114608
2434.60539278681881114608
两个答案都完全正确 - 您只是看到了浮点数学的影响之一。