Функция возвращает разные ответы с одинаковыми аргументами
Я перехожу из 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
У меня есть эта довольно простая программа, в которой я пытаюсь найти PDF при x=0 стандартной переменной N(0,1) (должно быть 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)
У меня нет слов для ответа в (б) и понятия не имею, что (с) даже означает.
1 ответ
Очень быстрый ответ на "неправильный результат" заключается в том, что в
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
, Это объясняет (с).