program analysis
implicit none
integer i, j, k, l
double precision a, b, c, d, e
integer binb(1:20),binc(1:20),bind1(1:20),bine(1:20)
real lower(1:20),upper(1:20), next
character(100) event
upper(1)=-2.7
lower(1)=-3.0
binb(1:20)=0
binc(1:20)=0
bind1(1:20)=0
bine(1:20)=0
next=.3
do l=2,20
lower(l)=lower(l-1)+next
upper(l)=upper(l-1)+next
end do
open(unit = 7, file="zpc_initial_momenta.dat")
do k=1, 10
read(7,'(A)') event
do j=1,4000
read(7,*) a, b, c, d, e
do i=1, 20
if(b>=lower(i) .and. b<upper(i)) then
binb(i)=binb(i)+1
end if
if(c>=lower(i) .and. c<upper(i)) then
binc(i)=binc(i)+1
end if
if(d>=lower(i) .and. d<upper(i)) then
bind1(i)=bind1(i)+1
end if
if(e>=lower(i) .and. e<upper(i)) then
bine(i)=bine(i)+1
end if
end do
end do
end do
close(7)
open(unit = 8, file="outputanalysis2.dat")
Write(8,*) 'The bins in each column are as follows:'
Write(8,*) 'FIRST COLUMN (MOMENTUM IN X DIRECTION)'
write(8,*) binb(1:20)
write(8,*) 'THE TOTAL COUNT IS', SUM(binb)
Write(8,*) 'SECOND COLUMN (MOMENTUM IN Y DIRECTION)'
write(8,*) binc(1:20)
write(8,*) 'THE TOTAL COUNT IS', SUM(binc)
Write(8,*) 'THIRD COLUMN (MOMENTUM IN Z DIRECTION)'
write(8,*) bind1(1:20)
write(8,*) 'THE TOTAL COUNT IS', SUM(bind1)
Write(8,*) 'FOURTH COLUMN (KINETIC ENERGY)'
write(8,*) bine(1:20)
write(8,*) 'THE TOTAL COUNT IS', SUM(bine)
close(8)
end program
我有一个问题,我半信半疑是由于 Fortran 的 base 2 舍入错误,但我不完全确定:在我设计用于计算不同范围数据的 if 语句中,我有一个数组用于上限和每个箱子的下限。我以前的程序没有使用数组,但非常冗长。在我的数组程序中,在执行程序时,一些箱子最多关闭 3 个计数(不是全部,其中一些箱子关闭少于那个或根本没有。)我做了一些进一步的挖掘并比较了它到声明的非数组变量等于 bin 的上限和下限之一,并将其打印出来。例如:假设 bin 编号 5,其 bin 长度为(-1.8 到 -1.5),它计算此范围内的值。当我使用非数组上下界查看bin计数是否有变化时,有:它是897,这是正确的bin计数(在之前的非数组程序中找到。)但是,当我使用定义每个上限和下限的数组,将它们放入 if 语句(如本程序所示),计数为 900。为了查看发生了什么,然后我让我的程序打印出等于 -1.8 的非数组变量。执行程序时打印出:-1.79999995。当我让我的程序打印出等效的数组下限 (lower(5)) 时,它会打印出 -1.80000019。有人可以向我解释这里发生了什么,如果这就是我的数组程序的计数略有下降的原因?有没有办法来解决这个问题?谢谢!
我无法重现你的错误,因为我没有数据,但你的代码应该没问题,除非你需要高精度。我建议您对所有浮点变量和参数使用
real*8
,并以相同的精度赋值:如next=0.3d0
。我上传了一个对我有用的最小代码。希望有所帮助。
program analysis
implicit none
integer :: i, j, k, l
real*8 :: a, b, c, d, e
integer :: binb(1:20),binc(1:20),bind1(1:20),bine(1:20)
real*8 :: lower(1:20),upper(1:20), next
integer :: bincheck
upper(1)=-2.7d0
lower(1)=-3.0d0
binb(1:20)=0
next=0.3d0
do l=2,20
lower(l)=lower(l-1)+next
upper(l)=upper(l-1)+next
end do
open(unit = 100, file="zpc_initial_momenta.dat")
do j=1,300
read(100,*) b
do i=1, 20
if(b>=lower(i) .and. b<upper(i)) then
binb(i)=binb(i)+1
end if
end do
end do
close(100)
!-------- check --------
do i=1,20
write(*,*) binb(i)
enddo
open(unit = 100, file="zpc_initial_momenta.dat")
bincheck = 0
do i=1,300
read(100,*) b
if(b>=lower(1) .and. b<upper(1)) then
bincheck = bincheck +1
end if
enddo
write(*,*) 'values in bin 1', bincheck
close(100)
end program