我正在从MATLAB过渡到Fortran,并遇到了我从未期望过的各种奇怪的行为。这是让我困惑的一个:
Program pruebanormal
double precision :: g01eaf, x, y
character :: T*1
integer :: Iffail
Iffail = 0
T = 'L'
x = 0.0
y = g01eaf('L',0.0,Iffail)
write(*,*) 'y = ',y
end program pruebanormal
我有这个相当简单的程序,其中我试图在标准N(0,1)变量的x = 0处找到pdf(应该是0.5)。 g01eaf()
是NAG库函数,它为我执行此操作。我正在使用gfortran进行编译。
保持程序的其余部分不变,取决于我在g01eaf()
中编写参数的方式,我会得到不同的答案:
a) g01eaf(T,x,Iffail)
b) g01eaf(T,0.0,Iffail)
c) g01eaf(T,x,0)
现在,在MATLAB下,我会得到相同(正确)的答案:y = 0.500000。但是,在Fortran下,我得到了:
a) y = 0.500000
b) y = 1.000000
c) Program received signal SIGSEGV: Segmentation fault - invalid memory reference.
Backtrace for this error:
#0 0xB766C163
#1 0xB766C800
#2 0xB77763FF
#3 0x804982E in g01eafn_
Violación de segmento (`core' generado)
我对(b)中的答案一无所知,也不知道(c)甚至意味着什么。
答案 0 :(得分:7)
“错误结果”的快速答案是
y = g01eaf('L',0.0,Iffail)
你传递的是不同类型的真实变量而不是
double precision x
x = 0.0 ! x is still double precision.
y = g01eaf('L',x,Iffail)
函数g01eaf
可能需要双精度:你应该仔细阅读NAG的文档。
y = g01eaf('L', 0d0, Iffail)
现在详细说明。
您不希望经常出现这些问题。您希望确保接口可用于g01eaf
的函数调用。然后,您的编译器会抱怨将真实的默认类型传递给函数。
假设您拥有该库的最新版本,您希望执行类似
的操作use nag_library, only : g01eaf, nag_wp
implicit none
integer Iffail
real(kind=nag_wp) y
y = g01eaf('L', 0._nag_wp, Iffail)
end
再次,请参阅文档。既可以用于库,也可以用于模块的含义等。
对于旧版本,应该仍然有一个模块可用,但可能会被称为不同的模块,并且可能未定义nag_wp
(意味着您必须仔细选择类型)。
该模块还会导致Iffail
要求设置的投诉,因此必须是变量,而不是0
。这解释了(c)。