是否可以使用NaN设置参数变量?并在特定的模块中。我想用它来初始化一些其他变量。因此,如果没有更新,我将面临运行时错误,而不是使用一些随机数运行的模拟。 我正在使用GFORTRAN。
答案 0 :(得分:8)
要添加到Vladimir F's answer,我会提到gfortran 5.0(但不是更早)支持IEEE内部模块。
而不是
real x
x=0
x=0/x
可以使用
use, intrinsic :: iso_fortran_env
use, intrinsic :: ieee_arithmetic
integer(int32) i
real(real32) x
x = ieee_value(x, ieee_quiet_nan)
i = transfer(x,i)
这使您可以灵活地获得所获得的NaN值。您也不必担心任何信号无效标志。 [但请注意,要求ieee_signaling_nan
可能不会真的给你。]
请注意,ieee_value()
无法在初始化中直接使用:对它的引用不是常量表达式。对于此类用法,请采用此方法获取位模式并应用其他答案的方法。
您还需要确保支持每种数据类型的功能。
答案 1 :(得分:7)
有可能。首先,您必须找出哪个位模式代表可能的NaN值之一。您可以将位模式存储为整数:
use, intrinsic :: iso_fortran_env
real(real64) x
integer(int64) i
x = 0
x = 0/x
print *, x
print *, transfer(x, i)
end
它给出:-2251799813685248
然后您可以使用
初始化变量real(real64), parameter :: nan64 = transfer(-2251799813685248_int64, 1._real64)
类似地,对于32位变量,您将获得整数-4194304,以便您可以执行
real(real32), parameter :: nan32 = transfer(-4194304_int32, 1._real32)
许多编译器可以选择为您执行所有实际变量。正如francescalus所示,在gfortran中它是-finit-real=nan
。手动执行此操作可以更好地控制。
免责声明:切换到其他平台时要小心。 Endianness和其他问题可能会发挥作用,即使我认为它实际上可以。我假设一个符合IEEE标准的CPU。
请参阅francescalus对使用标准功能的替代方案的回答。不幸的是,它不适用于parameter
常量,但很有用。
答案 2 :(得分:0)
如果您遇到没有内在IEEE但具有内在iso_c_binding(如在Windows上构建R所需的那个)的GFortran,则以下工作并且相当于C和R NaN(传递{ R)上的{1}}:
is.nan
有趣的是,real(kind = c_double), parameter :: ONE = 1_c_double
real(kind = c_double), parameter :: NAN = TRANSFER(z'7FF0000000000001', ONE)
无法检查real(kind = c_double), parameter :: NAN = TRANSFER(z'7FF0000000000001', 1_c_double)
。