Fortran语言中的无穷大
在Fortran中将变量设置为+无穷大最安全的方法是什么?目前我正在使用:Fortran语言中的无穷大,fortran,infinity,Fortran,Infinity,在Fortran中将变量设置为+无穷大最安全的方法是什么?目前我正在使用: program test implicit none print *,infinity() contains real function infinity() implicit none real :: x x = huge(1.) infinity = x + x end function infinity end program test 但我想知道是否有更好的方法?
program test
implicit none
print *,infinity()
contains
real function infinity()
implicit none
real :: x
x = huge(1.)
infinity = x + x
end function infinity
end program test
但我想知道是否有更好的方法?我不知道最安全的方法,但我可以为您提供另一种方法。我学会了这样做:
PROGRAM infinity
IMPLICIT NONE
INTEGER :: inf
REAL :: infi
EQUIVALENCE (inf,infi) !Stores two variable at the same address
DATA inf/z'7f800000'/ !Hex for +Infinity
WRITE(*,*)infi
END PROGRAM infinity
如果您在表达式中使用异常值(我认为这通常是不可取的),您应该仔细注意编译器如何处理它们,否则可能会得到一些意外的结果 如果编译器ISO TR 15580 IEEE算术是所谓Fortran 2003标准的一部分,则可以使用IEEE_*模块中的程序
PROGRAM main
USE ieee_arithmetic
IMPLICIT NONE
REAL :: r
IF (ieee_support_inf(r)) THEN
r = ieee_value(r, ieee_negative_inf)
END IF
PRINT *, r
END PROGRAM main
我不会依赖编译器来支持IEEE标准,也不会像您那样做,但有两个变化:
maging(1.)+maging(1.)
,因为在某些编译器上,您可能最终会遇到-maging(1.)+1
——这可能会导致内存泄漏(不知道原因,但可以说这是一个实验事实)real
类型。我个人更喜欢将所有浮点数保留为real*8
,因此所有浮点数常量都用d0
限定,如下所示:maging(1.d0)
。当然,这不是规则;有些人喜欢同时使用real
-s和real*8
-s我不确定下面的解决方案是否适用于所有编译器,但它是一种很好的数学方法,可以作为-log(0)达到无穷大 对复杂变量也很有效。这似乎对我很有效。 定义一个参数
double precision,parameter :: inf = 1.d0/0.d0
然后在if测试中使用它
real :: sng
double precision :: dbl1,dbl2
sng = 1.0/0.0
dbl1 = 1.d0/0.d0
dbl2 = -log(0.d0)
if(sng == inf) write(*,*)"sng = inf"
if(dbl1 == inf) write(*,*)"dbl1 = inf"
if(dbl2 == inf) write(*,*)"dbl2 = inf"
read(*,*)
使用ifort&run编译时,我得到
sng = inf
dbl1 = inf
dbl2 = inf
real*8
和double-precision
(1.d0
)不一定是完全相同的实数类型。当然,使用单精度还是双精度不是个人偏好的问题,而是数学论证和测试的问题。如果不启用FPE捕获,它将在符合IEEE标准的机器上工作。但如果你处理无穷大,那么这样做是愚蠢的,至少在gfortran中是不行的。它会引发编译器错误。
sng = inf
dbl1 = inf
dbl2 = inf