我通常是Fortran的新手,我有一个项目,我的教授希望班级尝试找到pi。要做到这一点,他希望我们创建自己的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
这个子程序是基于arctan近似的泰勒级数,并且似乎工作得很好,因为我通过调用它来测试它。
real*8:: arc=0.0, approx
call arctan(1.d0,10000000,arc)
approx = arc*4
我从我的主程序中调用了这个程序,它应该返回pi并且我得到了
approx = 3.1415926335902506
这对我来说足够接近了。当我尝试
时会出现问题pi = 16 * arctan(1/5) - 4 * arctan(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
,这显然不是pi。每次调用arctan子程序时,arc都会重置,所以我知道这不是问题所在。我认为问题在于我在宣布first
和second
之前如何调用子例程,但我不知道如何改进它们。
我做错了什么?
编辑:
我实际上解决了这个问题,实际的问题只是fortran决定它不想做approx = first - second
并且正在制作它以便约= =第二我不知道为什么,但我通过用以下内容替换该语句来解决问题:
approx = (second-first)
approx = approx *(-1)
并且看起来很愚蠢,现在效果很好,结果为3.1415926535897940!
答案 0 :(得分:0)
问题是由不同类型(单/双精度)产生的 arctan调用中的变量弧和子程序的实现。迭代计数10000 ...太多了,可能会导致数值问题,只需100就足够了(而且速度更快......)。
提示:对所有prog和过程始终使用隐式none。在这里编译器会立即告诉你,你忘了声明arc ...
只需在主程序中使其达到双倍精度即可获得所需的答案。