在FORTRAN中具有带NaN值的参数(常量)变量

时间:2015-08-12 17:32:57

标签: fortran nan gfortran

是否可以使用NaN设置参数变量?并在特定的模块中。我想用它来初始化一些其他变量。因此,如果没有更新,我将面临运行时错误,而不是使用一些随机数运行的模拟。 我正在使用GFORTRAN。

3 个答案:

答案 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)