fortran - Fortran 中非常少的数字变为负数
问题描述
我正在 Fortran90 中做一个程序,它从i=1
给定的i=n
地方做一个总和n
。总和是sum_{i=1}^{i=n}1/(i*(i+1)*(i+2))
。这个和收敛到 0.25。这是代码:
PROGRAM main
INTEGER n(4)
DOUBLE PRECISION s(4)
INTEGER i
OPEN(11,FILE='input')
OPEN(12,FILE='output')
DO i=1,4
READ(11,*) n(i)
END DO
PRINT*,n
CALL suma(n,s)
PRINT*, s
END
SUBROUTINE suma(n,s)
INTEGER n(4),j,k
DOUBLE PRECISION s(4),add
s=0
DO k=1,4
DO j=1,n(k)
add=1./(j*(j+1)*(j+2))
s(k)=s(k)+add
END DO
END DO
END SUBROUTINE
输入
178
1586
18232
142705
该output
文件现在是空的,我需要对其进行编码。我只是打印结果,它们是:
0.249984481688 0.249999400246 0.248687836759 0.247565846142
问题与变量有关add
。当j
更大时,add
变为负数,并且总和不能很好地收敛。我该如何解决?
解决方案
这可能是实现您想要的更好的方法。我确实删除了 IO。程序的输出是
% gfortran -o z a.f90 && ./z
178 0.249984481688392
1586 0.249999801599584
18232 0.249999998496064
142705 0.249999999975453
program main
implicit none ! Never write a program without this statement
integer, parameter :: knd = kind(1.d0) ! double precision kind
integer n(4)
real(knd) s(4)
integer i
n = [178, 1586, 18232, 142705]
call suma(n, s)
do i = 1, 4
print '(I6,F18.15)', n(i), s(i)
end do
contains
!
! Recursively, sum a(j+1) = j * a(j) / (j + 1)
!
subroutine suma(n, s)
integer, intent(in) :: n(4)
real(knd), intent(out) :: s(4)
real(knd) aj
integer j, k
s = 0
do k = 1, 4
aj = 1 / real(1 * 2 * 3, knd) ! a(1)
do j = 1, n(k)
s(k) = s(k) + aj
aj = j * aj / (j + 3)
end do
end do
end subroutine
end program main
推荐阅读
- go - 是否可以解析 k8s 非结构化的状态字段。非结构化
- amazon-web-services - 我在谷歌的 ip 是什么给了我我的 Ip。如果我将其作为入站规则放在 AWS RDS 安全组中,是否只允许访问我的计算机
- javascript - if...else 在 JavaScript 中的逻辑问题
- git - git tortoise:2.1 错误代码128,“致命:远程端意外挂断”
- gatsby - 使用 gatsby-source-figma 插件运行 Gatsby 服务器时重复出现错误
- c# - Windows 窗体控件自定义集合正在使设计器崩溃而不报告任何错误
- ms-word - 有没有办法编写 Microsoft Word 脚本来自动保存所有打开的文档?
- java - 将 Spring Boot 从 2.1.x 升级到 2.3.3 时无法获取云配置
- java - 将 JWT 部署为远程服务或公共库
- twilio - 我可以在不发送传真的情况下测试 Twilio 传真侦听页面吗