我一直试图找到符合标准的方法来检查Fortran 90/95中的无限和NaN值,但事实证明它比我想象的更难。
ieee_arithmetic
和ieee_is_nan()
内在函数的内在ieee_is_finite()
模块。但是,从版本4.9开始,所有编译器都不支持它(notably gfortran。)在开头定义无穷大和NaN,如pinf = 1. / 0
和nan = 0. / 0
似乎对我来说是骇人听闻的,恕我直言会引发一些构建问题 - 例如,如果某些编译器在编译时检查这个问题,则必须提供一个特别旗帜。
我有没有办法在标准的Fortran 90/95中实现?
function isinf(x)
! Returns .true. if x is infinity, .false. otherwise
...
end function isinf
和isnan()
?
答案 0 :(得分:21)
不使用ieee_arithmatic
的简单方法是执行以下操作。
无限:定义变量infinity = HUGE(dbl_prec_var)
(或者,如果有的话,定义四元精度变量)。然后,您只需通过if(my_var > infinity)
检查您的变量是否为无穷大。
NAN :这更容易。根据定义,NAN不等于任何东西,甚至本身。只需将变量与自身进行比较:if(my_var /= my_var)
。
答案 1 :(得分:3)
我没有足够的代表评论所以我会“回答”关于Rick Thompson关于测试无限的建议。
if (A-1 .eq. A)
如果A是一个非常大的浮点数,并且1
低于A的精度,则也是如此。
一个简单的测试:
subroutine test_inf_1(A)
real, intent(in) :: A
print*, "Test (A-1 == A)"
if (A-1 .eq. A) then
print*, " INFINITY!!!"
else
print*, " NOT infinite"
endif
end subroutine
subroutine test_inf_2(A)
real, intent(in) :: A
print*, "Test (A > HUGE(A))"
if (A > HUGE(A)) then
print*, " INFINITY!!!"
else
print*, " NOT infinite"
endif
end subroutine
program test
real :: A,B
A=10
print*, "A = ",A
call test_inf_1(A)
call test_inf_2(A)
print*, ""
A=1e20
print*, "A = ",A
call test_inf_1(A)
call test_inf_2(A)
print*, ""
B=0.0 ! B is necessary to trick gfortran into compiling this
A=1/B
print*, "A = ",A
call test_inf_1(A)
call test_inf_2(A)
print*, ""
end program test
输出:
A = 10.0000000
Test (A-1 == A)
NOT infinite
Test (A > HUGE(A))
NOT infinite
A = 1.00000002E+20
Test (A-1 == A)
INFINITY!!!
Test (A > HUGE(A))
NOT infinite
A = Infinity
Test (A-1 == A)
INFINITY!!!
Test (A > HUGE(A))
INFINITY!!!
答案 2 :(得分:2)
没有
用于生成/检查NaN的IEEE_ARITHMETIC的显着部分很容易为特定体系结构的gfortran编写。
答案 3 :(得分:1)
我用过:
PROGRAM MYTEST
USE, INTRINSIC :: IEEE_ARITHMETIC, ONLY: IEEE_IS_FINITE
DOUBLE PRECISION :: number, test
number = 'the expression to test'
test = number/number
IF (IEEE_IS_FINITE(test)) THEN
WRITE(*,*) 'We are OK'
ELSE
WRITE(*,*) 'Got a problem'
END IF
WRITE(*,*) number, test
END PROGRAM MYTEST
这将打印出来'遇到问题'数字= 0.0D0,1.0D0 / 0.0D0,0.0D0 / 0.0D0,SQRT(-2.0D0),以及数字= EXP(1.0D800)或数字= EXP(-1.0D800)等溢出和下溢。请注意,通常,数字= EXP(1.0D-800)之类的东西只会设置数字= 1.0并在编译时产生警告,但是程序会打印“我们没事”,我认为这是可以接受的。
OL。
答案 4 :(得分:0)
没有
在Fortran 90/95中也没有符合标准的检查无穷大或NaN的方法,也没有符合标准的方法。在Fortran 90/95中没有符合标准的方法来定义这些准数字。
答案 5 :(得分:0)
对于Fortran,1 / infinity = 0 因此,将您的变量除以零 即
Access-Control-Allow-Origin: '*'
有您的无限大检查。无需并发症。
答案 6 :(得分:0)
测试NaN都不起作用,例如,如果测试真正的s2p以查看是否为NaN,则
if(isnan(s2p))
在gfortran中也不起作用
if(s2p.ne.s2p).
唯一起作用的是
if(.not.s2p<1.and..not.s2p>1)
尽管可以确保您可能要添加
if(.not.s2p<1.and..not.s2p>1.and..not.s2p==1)
答案 7 :(得分:-2)
对于Inf,似乎有效的是,如果(A-1 .eq.A)为真,则A为Inf