函数返回具有相同参数的不同答案

use*_*208 2 matlab fortran arguments nag-fortran

我正在从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
Run Code Online (Sandbox Code Playgroud)

我有这个相当简单的程序,我试图在标准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)
Run Code Online (Sandbox Code Playgroud)

现在,在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)
Run Code Online (Sandbox Code Playgroud)

我对(b)中的答案一无所知,也不知道(c)甚至意味着什么.

fra*_*lus 7

对"错误结果"的快速回答是

y = g01eaf('L',0.0,Iffail)
Run Code Online (Sandbox Code Playgroud)

你传递的是一种不同类型的真实变量

double precision x
x = 0.0   ! x is still double precision.
y = g01eaf('L',x,Iffail)
Run Code Online (Sandbox Code Playgroud)

该函数g01eaf可能需要双精度:您应该仔细阅读NAG的文档.

y = g01eaf('L', 0d0, Iffail)
Run Code Online (Sandbox Code Playgroud)

现在来详细说明.

你不希望这些问题经常发生.您希望确保接口可用于函数调用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
Run Code Online (Sandbox Code Playgroud)

再次,请参阅文档.既可以用于库,也可以用于模块的含义等.

对于旧版本,一个应该仍然有一个模块可用,但它可能被称为不同的东西,nag_wp可能没有定义(意味着你必须仔细选择种类).

该模块还将导致Iffail需要设置的投诉,因此必须是变量,而不是0.这解释了(c).