fortran - Fortran arctan 子例程未按预期工作
问题描述
我通常是 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
这个子程序基于用于反正切近似的泰勒级数,并且似乎工作得很好,因为我通过调用它来测试它。
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
and之前如何调用子例程second
,但我不知道我能做些什么来改进它们。
我究竟做错了什么?
编辑:我实际上解决了这个问题,而实际问题只是 fortran 决定它不想这样做approx = first - second
并且正在制作它,所以大约 == second 我不知道为什么,但我通过用以下语句替换该语句解决了这个问题:
approx = (second-first)
approx = approx *(-1)
尽管看起来很愚蠢,但它现在可以完美运行,结果为 3.1415926535897940!
解决方案
该问题是由 arctan 调用中变量 arc 的不同类型(单精度/双精度)和子程序的实现引起的。10000 次的迭代次数...太多了,可能会导致数值问题,仅 100 次就足够了(而且速度更快...)。
提示:始终对所有 progs 和过程使用隐式 none。在这里,编译器会立即告诉您您忘记声明 arc...
只需在主程序中将其设为双精度,您就会得到所需的答案。
推荐阅读
- regex - Dialogflow RegEx 字母数字(语音)
- javascript - 遍历列表项以设置装饰值
- javascript - MSAL.js acquireTokenSilent 生成的空令牌
- python-3.x - Pandas 文件更新/替换另一个参考文件中的值
- c# - 属性更改时重新启动可观察订阅
- reactjs - ./src/components/Car.js 模块未找到:无法解析 'C:\Users\Felix\source\repos\React\car-app\src\components 中的 'react-table/react-table.css' '
- testing - 如何关闭单个文件的 Jasmine 随机化?
- javascript - 可以阻止 node.js 工作人员退出主进程吗
- python - Python 导入错误 - 没有模块命名错误
- hiveql - 如何在 Hiveql 中添加迄今为止的年份