2

我正在从 MATLAB 过渡到 Fortran,并遇到了 MATLAB 从未预料到的各种奇怪行为。这是让我感到困惑的一个:

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) 变量(应该是 0.5)的 x=0 处的 pdf。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) 是什么意思。

4

1 回答 1

8

“错误结果”的快速答案是

y = g01eaf('L',0.0,Iffail)

您传递的实变量类型不同于 in

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)。

于 2014-05-30T06:53:56.457 回答