Фортран Арктан подпрограмма не работает, как ожидалось - PullRequest
0 голосов
/ 28 апреля 2018

Я вообще новичок в Фортране, и у меня есть проект, в котором мой профессор хочет, чтобы класс попытался найти пи. Для этого он хочет, чтобы мы создали нашу собственную подпрограмму arctan и использовали это конкретное уравнение: pi = 16 * arctan (1/5) - 4 * arctan (1/239).

Поскольку профессор не позволил мне использовать встроенную функцию ATAN, я создал подпрограмму, которая приближается к ней:

subroutine arctan(x,n,arc)
    real*8::x, arc
    integer::n, i
    real*8::num, nm2
    arc = 0.0
    do i=1,n,4
    num = i
    nm2 = num+2
    arc = arc+((x**num)/(num)) - (x**(nm2)/(nm2))
    enddo
    end subroutine arctan

Эта подпрограмма основана на серии Тейлора для арктанового приближения и, похоже, отлично работает, потому что я проверил ее, вызвав это.

real*8:: arc=0.0, approx
call arctan(1.d0,10000000,arc)
approx = arc*4

Я вызвал это из моей основной программы, которая должна вернуть пи, и я получил

approx = 3.1415926335902506 

что достаточно близко для меня. Проблема возникает, когда я пытаюсь сделать

пи = 16 * арктан (1/5) - 4 * арктан (1/239). Я попробовал это:

real*8:: first, second
integer:: n=100
    call arctan((1.d0/5.d0), n, arc)
    first = 16*arc
    call arctan((1.d0/239.d0), n, arc)
    second = 4.d0*arc
    approx = first - second

и как-то approx = 1.67363040082988898E-002, что явно не пи. дуга сбрасывается при каждом вызове подпрограммы arctan, поэтому я знаю, что это не проблема. Я думаю, проблема в том, как я вызываю подпрограмму, прежде чем объявить first и second, но я не знаю, что я мог бы сделать, чтобы улучшить их.

Что я делаю не так?

EDIT: Я на самом деле решил проблему, и фактическая проблема была только что Фортран решил, что он не хочет делать approx = first - second и делал так, чтобы примерно == секунду я понятия не имел почему, но я решил проблему, заменив это утверждение следующим:

approx = (second-first)
approx = approx *(-1)

и как бы глупо это не выглядело, теперь оно отлично работает, с результатом 3.1415926535897940!

1 Ответ

0 голосов
/ 28 апреля 2018

Проблема возникает из-за различных типов (одинарная / двойная прецизионность) переменная дуга в вызове arctan и реализация подпрограммы. Число итераций 10000 ... слишком много и может вызвать численные проблемы, просто 100 более чем достаточно (и гораздо быстрее ...).

Совет: всегда используйте неявное none для всех программ и процедур. Здесь компилятор сразу сказал бы вам, что вы забыли объявить дугу ...

Просто сделайте двойную точность в основной программе, и вы получите желаемый ответ.

...