Странное поведение Fortran 90

program main
call findbracket(x0, a, b)
end program

function f(x)
double precision x,f
f = x
end function

subroutine findbracket(x0,a,b)
double precision x0, a, b
double precision fa, fb
double precision dx
dx = 0.001d0
x0 = 1.0d0
a = x0
b = x0
print*, a, b
print*, f(a)
print*, f(b)

do
fa = f(a)
fb = f(b)

print*, "what is fa", fa
print*, "what is fb", fb
a = a - dx

if (fa*fb < 0) then
        exit
end if
print*, b, dx
b = b + dx
if (fa*fb < 0) then
        exit
end if

dx = dx*2

end do

end subroutine 

Я пишу программу, которая решает корень заданной функции f (x). На этом этапе я просто хочу проверить, получаю ли я правильное значение для каждого шага, и заметил некоторые ошибки. Чтобы упростить задачу, у меня есть функция f (x) = x, и я ожидал, что программа напечатает f (a) = 1.0 и f (b) = 1.0, но результат будет f (a) = 1.8750000000000000 и f (b ) = 0,0000000000000000. Плюс, хотя я установил как a, так и b равными x0, кажется, что это a = 1.0000002381857485 и b = 1.0000000000000000. Может ли кто-нибудь объяснить, почему это происходит? Возможно, я упускаю какую-то глупость, но я не могу этого найти. Я ценю вашу помощь.


person mike    schedule 17.10.2016    source источник
comment
Замените строку end program строкой, содержащей слово contains. В конце исходного файла, содержащего весь ваш код, добавьте строку end program. Затем сразу после начала строки program (т.е. после этой первой строки) вставьте строку implicit none. Затем (повторно) скомпилируйте и посмотрите, что вам скажет компилятор.   -  person High Performance Mark    schedule 17.10.2016
comment
Я определил x0 = 1.0d0, a = x0, b = x0 в основной программе, и теперь все работает так, как я задумал. И a, и b печатают ровно 1.0. Но у меня все еще проблема с функцией. fa и fb печатают 0.0000000000000000. Я не уверен, почему функция так работает ..   -  person mike    schedule 17.10.2016
comment
В качестве альтернативы подходу contains вы можете просто добавить implicit none в подпрограмму (а в идеале и где-нибудь еще). Это поможет вам сделать вывод, что f в подпрограмме - это функция с результатом real, а не double precision. Естественно, должно быть последнее.   -  person francescalus    schedule 17.10.2016
comment
Я пробовал «неявное отсутствие», и это дает мне, что f не имеет неявного типа, но я указал, что x и f в функции f (x) имеют двойную точность .. Как я могу изменить f на функцию с результатом с двойной точностью?   -  person mike    schedule 17.10.2016
comment
См. stackoverflow.com/questions/ 24337413 /   -  person Vladimir F    schedule 17.10.2016
comment
Помимо ссылки о implicit none выше, у нас есть документация по структуре программы. По сути, если вы не пойдете на contains подход, упомянутый первым, тогда f в подпрограмме необходимо соответствующим образом объявить: double precision f (что дает ей неявный интерфейс). Без contains, содержащего и функцию, и подпрограмму, они обе являются внешними процедурами и ничего не знают друг о друге без явных подробностей.   -  person francescalus    schedule 17.10.2016


Ответы (1)


Добавьте эти строки в свою подпрограмму

subroutine findbracket(x0,a,b)
double precision x0, a, b
double precision fa, fb
double precision dx

interface
    function f(x)
    double precision x,f
    end function
end interface

тогда вы должны получить правильное значение для f (x).

Редактировать:

Интерфейс делает функцию f (x) видимой (и используемой) в подпрограмме.

person Alex    schedule 27.01.2017
comment
Всегда полезно объяснить, зачем добавлять эти строки, что они означают. - person Vladimir F; 28.01.2017