为什么 Python 和 Fortran77 return 这个分数的值不同?
Why do Python and Fortran77 return different values for this fraction?
长话短说,我正在尝试在 Python 中重写顾问发给我的 Fort运行77 代码,因为 Python 对我来说更方便。
当我测试我的代码时,我意识到我的输出与 Fort运行 代码略有不同。似乎所有这些都源于 Fort运行.
中的一些舍入错误或诸如此类的东西
例如Python中的分数277./14336.
returns:
print(277./14336.)
> 0.019321986607142856
^
但是在 Fort运行77 我得到:
program foo
implicit none
real*8 x
x=277./14336.
write(*,*) x
end program
> 1.9321987405419350E-002
^
因此这些数字直到第 8 位有效数字都相等,通常应该足够好。但是当我尝试评估数值精度时,我的代码有一些微调取消(正好是 10^8 中的第 1 部分),因此 Fort运行 的误差估计有时是 [= 的两倍26=]代码。
这是怎么回事?首先我认为这是因为 Fort运行 在 32 位中是 运行 而在 64 位中是 Python 运行。但是当我 运行 32 位版本的 Python 时我得到了相同的结果(尽管我不确定它是否有所不同,因为我仍在使用 64 位 OS)我读到 Fort运行 中的 real*8
表示 8 字节精度或 64 位。 Python 和 Fort运行 中浮点数的表示有根本区别吗?
Python的回答比较准确
在 Fortran 中,您将结果分配给 64 位浮点数,但输入是 32 位浮点数。所以在32位模式下做除法,然后在赋值的时候把结果放宽到64位
在计算中使用 64 位浮点数,您应该会得到正确的结果。
$ cat div.f90
Program div
Use, Intrinsic :: iso_fortran_env, Only : wp => real64
Implicit None
Real( wp ) :: x
x = 277.0_wp / 14336.0_wp
Write( *, * ) x
End Program div
$ gfortran -Wall -Wextra -std=f2008 -fcheck=all div.f90
$ ./a.out
1.9321986607142856E-002
长话短说,我正在尝试在 Python 中重写顾问发给我的 Fort运行77 代码,因为 Python 对我来说更方便。 当我测试我的代码时,我意识到我的输出与 Fort运行 代码略有不同。似乎所有这些都源于 Fort运行.
中的一些舍入错误或诸如此类的东西例如Python中的分数277./14336.
returns:
print(277./14336.)
> 0.019321986607142856
^
但是在 Fort运行77 我得到:
program foo
implicit none
real*8 x
x=277./14336.
write(*,*) x
end program
> 1.9321987405419350E-002
^
因此这些数字直到第 8 位有效数字都相等,通常应该足够好。但是当我尝试评估数值精度时,我的代码有一些微调取消(正好是 10^8 中的第 1 部分),因此 Fort运行 的误差估计有时是 [= 的两倍26=]代码。
这是怎么回事?首先我认为这是因为 Fort运行 在 32 位中是 运行 而在 64 位中是 Python 运行。但是当我 运行 32 位版本的 Python 时我得到了相同的结果(尽管我不确定它是否有所不同,因为我仍在使用 64 位 OS)我读到 Fort运行 中的 real*8
表示 8 字节精度或 64 位。 Python 和 Fort运行 中浮点数的表示有根本区别吗?
Python的回答比较准确
在 Fortran 中,您将结果分配给 64 位浮点数,但输入是 32 位浮点数。所以在32位模式下做除法,然后在赋值的时候把结果放宽到64位
在计算中使用 64 位浮点数,您应该会得到正确的结果。
$ cat div.f90
Program div
Use, Intrinsic :: iso_fortran_env, Only : wp => real64
Implicit None
Real( wp ) :: x
x = 277.0_wp / 14336.0_wp
Write( *, * ) x
End Program div
$ gfortran -Wall -Wextra -std=f2008 -fcheck=all div.f90
$ ./a.out
1.9321986607142856E-002