我一直试图找到一种符合标准的方法来检查Fortran 90/95中的无限值和NaN值,但事实证明这比我想象的要困难。
ieee_is_nan()
和ieee_is_finite()
内在函数的内部ieee_is_nan()
模块。然而,并不是所有编译器都支持它(特别是gfortran在4.9版时)。在一开始定义无穷大和NaN (比如pinf = 1. / 0
和nan = 0. / 0
)对我来说似乎有点麻烦,而IMHO可能会引发一些构建问题--例如,如果一些编译器在编译时检查它,那么就必须提供一个特殊的标志。
有什么方法可以在标准的Fortran 90/95中实现吗?
function isinf(x)
! Returns .true. if x is infinity, .false. otherwise
...
end function isinf
和isnan()
发布于 2013-06-30 14:50:34
不使用ieee_arithmatic
的简单方法是执行以下操作。
Infinity:定义变量infinity = HUGE(dbl_prec_var)
(如果有,则定义四精度变量)。然后,您可以通过if(my_var > infinity)
简单地检查变量是否为无穷大。
NAN:这就更容易了。按照定义,NAN并不等于任何东西,甚至其本身。简单地将变量与其自身进行比较:if(my_var /= my_var)
。
发布于 2014-12-31 16:55:34
我没有足够的代表来评论,所以我会“回答”里克汤普森关于测试无穷大的建议。
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!!!
发布于 2013-06-30 11:47:34
不是的。
用于生成/检查NaN的IEEE_ARITHMETIC的突出部分非常容易为特定体系结构的gfortran编写。
https://stackoverflow.com/questions/17389958
复制相似问题