Fortran 在数组中存储值的方式是否不同于非数组声明的变量?

问题描述 投票:0回答:1
    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。有人可以向我解释这里发生了什么,如果这就是我的数组程序的计数略有下降的原因?有没有办法来解决这个问题?谢谢!

arrays fortran gfortran fortran90
1个回答
0
投票

我无法重现你的错误,因为我没有数据,但你的代码应该没问题,除非你需要高精度。我建议您对所有浮点变量和参数使用

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
© www.soinside.com 2019 - 2024. All rights reserved.