Fortran 中两个小数相减得到零
Two small number subtract get zero in Fortran
我正在编写一个高精度的 Fortran 代码。在这里,我试图使用 ISO_FORTRAN_ENV 来实现这一点。我发现如果我减去两个小数,我得到的答案将是零。但是如果我加上它们就好了。
这是我的程序:
program test
USE ISO_FORTRAN_ENV, ONLY : REAL32
IMPLICIT NONE
REAL(REAL32), PARAMETER :: RE_L=-1.7499576837060936950743114606, &
RE_R=-1.7499576837060933110499019727
REAL(REAL32) :: A
A=(RE_R)-(RE_L)
PRINT 20, A
20 FORMAT(f50.40)
end program test
我得到的结果是0.00000000000000000000000000000。同时我不知道为什么。
说来话长,大家可以搜索google一些重点作品,比如“
What Every Programmer Should Know About Floating-Point Arithmetic”,一些非常好的相关页面会出现。
简而言之,浮点数格式,无论是float还是double,都只能表示一定精度的数字。算法在某些情况下应该仔细设计以获得合理的精度,例如使(1.0+x)-1.0!=0.0的最小浮点数x定义为FLT_EPSILON,它的值比你大得惊人可能是预期的。
您在 REAL32 范围内遇到文字中的单精度有效数字。
跳转到 REAL64,在文字上添加双说明符 1.7499576837060933110499019727d+0
prompt$ gfortran toosmallorg.f90
prompt$ ./a.out
0.0000000000000004440892098500626161694527
即使使用REAL64 d字面量,也只能得到小数点后16位,显示结果是错误的。使用 REAL32 时,只能识别小数点后的 7 位数字(在这台 Fedora 机器的 gfortran 7.3 的默认设置下)。 REAL128 可能会为文字提供足够的摆动空间。
一般警告;不是 Fortran 或允许的数字精度方面的专家
我正在编写一个高精度的 Fortran 代码。在这里,我试图使用 ISO_FORTRAN_ENV 来实现这一点。我发现如果我减去两个小数,我得到的答案将是零。但是如果我加上它们就好了。
这是我的程序:
program test
USE ISO_FORTRAN_ENV, ONLY : REAL32
IMPLICIT NONE
REAL(REAL32), PARAMETER :: RE_L=-1.7499576837060936950743114606, &
RE_R=-1.7499576837060933110499019727
REAL(REAL32) :: A
A=(RE_R)-(RE_L)
PRINT 20, A
20 FORMAT(f50.40)
end program test
我得到的结果是0.00000000000000000000000000000。同时我不知道为什么。
说来话长,大家可以搜索google一些重点作品,比如“ What Every Programmer Should Know About Floating-Point Arithmetic”,一些非常好的相关页面会出现。
简而言之,浮点数格式,无论是float还是double,都只能表示一定精度的数字。算法在某些情况下应该仔细设计以获得合理的精度,例如使(1.0+x)-1.0!=0.0的最小浮点数x定义为FLT_EPSILON,它的值比你大得惊人可能是预期的。
您在 REAL32 范围内遇到文字中的单精度有效数字。
跳转到 REAL64,在文字上添加双说明符 1.7499576837060933110499019727d+0
prompt$ gfortran toosmallorg.f90
prompt$ ./a.out
0.0000000000000004440892098500626161694527
即使使用REAL64 d字面量,也只能得到小数点后16位,显示结果是错误的。使用 REAL32 时,只能识别小数点后的 7 位数字(在这台 Fedora 机器的 gfortran 7.3 的默认设置下)。 REAL128 可能会为文字提供足够的摆动空间。
一般警告;不是 Fortran 或允许的数字精度方面的专家