这个 Fortran 变量来自哪里?
Where does this Fortran variable come from?
谁能告诉我有关以下子程序中使用的 costh
变量的信息?子程序从哪里获得这个变量的值?是错误还是内置函数?
完整的子程序如下。
SUBROUTINE MOMENT(I,A,AP,MODE,EP,NCASC,ID)
COMMON/MOM/VY(99996),VZ(99996),VX(99996)
DIMENSION ERES(99996),FCT(99996)
COMMON/XQANG/SUM(300,10),MDIR,COSTH
EQUIVALENCE(ERES(1),VY(1)),(FCT(1),VZ(1))
IF(ID-2)10,30,40
C INITIALIZATION
10 N=1
NN=N+NCASC-1
DO 20 J=N,NN
VY(J)=EP*MDIR
VX(J)=0.
20 VZ(J)=EP*(1-MDIR)
GO TO 60
C
C CALCULATION OF MOMENT
C
CKM 30 RN4=RANF(0.)
30 RN4=RAN(ISEED) !KM
PHI=6.28318*RN4
SOX=2.*AP*EP/(A**2*931.5)
C BUG FIX A*(AP+A)REPLACED BY A**2 12/15/82
C IF(SOX.LT.0.)WRITE(*,943)AP,EP,A
VT=SQRT(SOX)
SOX=1.-COSTH**2
IF(SOX.LT.0.)SOX=0.
SINTH=SQRT(SOX)
VZSE=VT*COSTH
VYSE=VT*SINTH*SIN(PHI)
VXSE=VT*SINTH*COS(PHI)
VZ(I)=VZ(I)+VZSE
VY(I)=VY(I)+VYSE
VX(I)=VX(I)+VXSE
VZP=VZ(I)-VZSE*(A/AP+1.)
VYP=VY(I)-VYSE*(A/AP+1.)
VXP=VX(I)-VXSE*(A/AP+1.)
VPP2=VZP*VZP+VYP*VYP+VXP*VXP
EPART=AP*VPP2*469.
SOX=0.
IF(VPP2.GT.0.0)SOX=VZP/SQRT(VPP2)
C DO NOT USE QUICK FUNCTIONS HERE
ANG=ACOS(SOX)*180./3.1415927
CALL OUTEM(2,MODE,EPART,ANG)
GO TO 60
C
C END CALCULATION
C
40 VFTS=VX(I)**2+VY(I)**2+VZ(I)**2
ERES(I)=0.5*A*VFTS*931.5
IF(VFTS.NE.0.)GO TO 50
FCT(I)=0.0
GO TO 60
50 FCT(I)=ACOS(VZ(I)/SQRT(VFTS))*180./3.1415927
60 RETURN
END
这一行
COMMON/XQANG/SUM(300,10),MDIR,COSTH
通知子例程关于一个名为 XQANG
的 公共块 ,它有一个名为 COSTH
的元素。在没有其他信息的情况下,并且在那个年份的代码中,这很可能是一个 real
变量。
公共块是一种 early-Fortran 机制,用于在程序单元之间共享变量,例如在主程序和子程序之间。在直接使用中,相同的公共块声明将在多个位置找到,具有相同的变量列表。每个声明都引用相同的变量。
虽然有一个转折点,但要小心谨慎。公共块实际上是一个共享内存块,并不要求声明的每个实例标识相同的变量。公共块的一个常见用途是在一个位置声明一个包含 100 个实数的数组,但在其他地方声明两个数组,每个数组包含 50 个实数——相同的内存,不同的变量。
更好的是,它们还可以用来改变变量的类型(某种程度上)。公共块的一种用法可能包含一个占用 4 个字节的实数变量,而同一块的另一种用法可能在同一位置包含一个 4 字节整数变量 - 相同的位,不同的解释。
这些曲折是公共块被广泛弃用的原因之一。他们被弃用的另一个原因是他们模糊了变量的共享,现在我们大多数人更喜欢通过他们的参数列表显式地将参数传入和传出子例程。
我猜 50 岁以下的 Fortran 程序员中很少有人仍在使用它们编写新代码。但是 8 - 80 岁的 Fortran 程序员仍在编写包含它们的代码。
谁能告诉我有关以下子程序中使用的 costh
变量的信息?子程序从哪里获得这个变量的值?是错误还是内置函数?
完整的子程序如下。
SUBROUTINE MOMENT(I,A,AP,MODE,EP,NCASC,ID)
COMMON/MOM/VY(99996),VZ(99996),VX(99996)
DIMENSION ERES(99996),FCT(99996)
COMMON/XQANG/SUM(300,10),MDIR,COSTH
EQUIVALENCE(ERES(1),VY(1)),(FCT(1),VZ(1))
IF(ID-2)10,30,40
C INITIALIZATION
10 N=1
NN=N+NCASC-1
DO 20 J=N,NN
VY(J)=EP*MDIR
VX(J)=0.
20 VZ(J)=EP*(1-MDIR)
GO TO 60
C
C CALCULATION OF MOMENT
C
CKM 30 RN4=RANF(0.)
30 RN4=RAN(ISEED) !KM
PHI=6.28318*RN4
SOX=2.*AP*EP/(A**2*931.5)
C BUG FIX A*(AP+A)REPLACED BY A**2 12/15/82
C IF(SOX.LT.0.)WRITE(*,943)AP,EP,A
VT=SQRT(SOX)
SOX=1.-COSTH**2
IF(SOX.LT.0.)SOX=0.
SINTH=SQRT(SOX)
VZSE=VT*COSTH
VYSE=VT*SINTH*SIN(PHI)
VXSE=VT*SINTH*COS(PHI)
VZ(I)=VZ(I)+VZSE
VY(I)=VY(I)+VYSE
VX(I)=VX(I)+VXSE
VZP=VZ(I)-VZSE*(A/AP+1.)
VYP=VY(I)-VYSE*(A/AP+1.)
VXP=VX(I)-VXSE*(A/AP+1.)
VPP2=VZP*VZP+VYP*VYP+VXP*VXP
EPART=AP*VPP2*469.
SOX=0.
IF(VPP2.GT.0.0)SOX=VZP/SQRT(VPP2)
C DO NOT USE QUICK FUNCTIONS HERE
ANG=ACOS(SOX)*180./3.1415927
CALL OUTEM(2,MODE,EPART,ANG)
GO TO 60
C
C END CALCULATION
C
40 VFTS=VX(I)**2+VY(I)**2+VZ(I)**2
ERES(I)=0.5*A*VFTS*931.5
IF(VFTS.NE.0.)GO TO 50
FCT(I)=0.0
GO TO 60
50 FCT(I)=ACOS(VZ(I)/SQRT(VFTS))*180./3.1415927
60 RETURN
END
这一行
COMMON/XQANG/SUM(300,10),MDIR,COSTH
通知子例程关于一个名为 XQANG
的 公共块 ,它有一个名为 COSTH
的元素。在没有其他信息的情况下,并且在那个年份的代码中,这很可能是一个 real
变量。
公共块是一种 early-Fortran 机制,用于在程序单元之间共享变量,例如在主程序和子程序之间。在直接使用中,相同的公共块声明将在多个位置找到,具有相同的变量列表。每个声明都引用相同的变量。
虽然有一个转折点,但要小心谨慎。公共块实际上是一个共享内存块,并不要求声明的每个实例标识相同的变量。公共块的一个常见用途是在一个位置声明一个包含 100 个实数的数组,但在其他地方声明两个数组,每个数组包含 50 个实数——相同的内存,不同的变量。
更好的是,它们还可以用来改变变量的类型(某种程度上)。公共块的一种用法可能包含一个占用 4 个字节的实数变量,而同一块的另一种用法可能在同一位置包含一个 4 字节整数变量 - 相同的位,不同的解释。
这些曲折是公共块被广泛弃用的原因之一。他们被弃用的另一个原因是他们模糊了变量的共享,现在我们大多数人更喜欢通过他们的参数列表显式地将参数传入和传出子例程。
我猜 50 岁以下的 Fortran 程序员中很少有人仍在使用它们编写新代码。但是 8 - 80 岁的 Fortran 程序员仍在编写包含它们的代码。