在 geany 中除以零
Division by zero in geany
我正在尝试 运行 geany 中的子例程,但它让我不断发出以下警告
NPJ(I,J) = DBLE(((2)/((X(I+1))-(X(I-1))))*DBLE(-((1)/(X(I+1)-X(I)))-((1)/(X(I)-
X(I-1)))))+ &
1
Warning: Possible change of value in conversion from REAL(8) to INTEGER(4) at (1)
代码后跟
C(I,J) = -(RE(I,J))/NPJ(I,J)
在下一行。
每次我 运行 它给出的程序都会被零除。
代码在这里:
! PROJETO 1 - MÉTODOS EXPERIMENTAIS EM HIDRODINÂMICA
!******************************************
! *
! PROGRAMA PRINCIPAL *
! *
!******************************************
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
Parameter (NX = 100, NY = 100)
! DECLARAÇÃO DE VARIÁVEIS
COMMON/GRID/X(NX),Y(NY)
COMMON/RESI/RE(NX,NY)
COMMON/PTN/ POT(NX,NY)
CHARACTER*30 BOBO
! DEFINIÇÃO DOS ARQUIVOS DE ENTRADA E SAÍDA
OPEN(3,FILE = 'placa.dat')
OPEN(4,FILE = 'output.dat')
! ENTRADA DE DADOS
READ(3,*) BOBO,IMAX
WRITE(*,'(A30,I10)')BOBO,IMAX
READ(3,*) BOBO,JMAX
WRITE(*,'(A30,I10)')BOBO,JMAX
READ(3,*) BOBO,t
WRITE(*,'(A30,F10.3)')BOBO,t
READ(3,*) BOBO,NMAX
WRITE(*,'(A30,I10)')BOBO,NMAX
READ(3,*) BOBO,UA
WRITE(*,'(A30,D10.3)')BOBO,UA
READ(3,*) BOBO,UB
WRITE(*,'(A30,D10.3)')BOBO,UB
READ(3,*) BOBO,UC
WRITE(*,'(A30,D10.3)')BOBO,UC
READ(3,*) BOBO,UD
WRITE(*,'(A30,D10.3)')BOBO,UD
READ(3,*) BOBO,UP
WRITE(*,'(A30,D10.3)')BOBO,UP
READ(3,*) BOBO,PREC
WRITE(*,'(A30,D10.3)')BOBO,PREC
READ(3,*) BOBO,NPR
WRITE(*,'(A30,I10)')BOBO,NPR
READ(3,*) BOBO,ITE
WRITE(*,'(A30,I10)')BOBO,ITE
READ(3,*) BOBO,ILE
WRITE(*,'(A30,I10)')BOBO,ILE
READ(3,*) BOBO,XSF
WRITE(*,'(A30,F10.3)')BOBO,XSF
READ(3,*) BOBO,YSF
WRITE(*,'(A30,F10.3)')BOBO,YSF
!$$$$$$
!$$$$$$ WRITE(*,*)"Os dados de entrada estao corretos?"
!$$$$$$ WRITE(*,*)"1--------SIM"
!$$$$$$ WRITE(*,*)"2--------NAO"
!$$$$$$ READ(*,*)INF
!$$$$$$ IF(INF.EQ.2) STOP
! GERAÇÃO DA MALHA COMPUTACIONAL
CALL MALHA(IMAX,JMAX,DX,ITE,ILE,XSF,YSF,DY)
! ! CONDIÇÃO INICIAL
CALL INICIAL(IMAX,JMAX,UP)
!!! INÍCIO DAS ITERAÇÕES
CALL SOLVER(IMAX,JMAX,NMAX,PREC,N,NPR,DY,UA,UB,UD,ILE,ITE,t)
!! FIM DA EXECUÇÃO
STOP
END
!******************************************
! *
! SUBROTINA MALHA *
! *
!******************************************
SUBROUTINE MALHA(IMAX,JMAX,DX,ITE,ILE,XSF,YSF,DY)
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
PARAMETER (NX=100,NY=100)
COMMON/GRID/ X(NX),Y(NY)
DX=1.0D0/DBLE(ITE-ILE)
DO I=ILE,ITE
X(I)=DX*DBLE(I-ILE)
END DO
DO I=ITE,IMAX
X(I)=X(I-1)+((X(I-1)-X(I-2))*XSF)
END DO
DO I=ILE-1,1,-1
X(I)=X(I+1)+((X(I+1)-X(I+2))*XSF)
END DO
Y(1) = (-DX)/2.0D0
Y(2) = DX/2.0D0
DY = Y(2)-Y(1)
DO J=3, JMAX
Y(J)=Y(J-1)+((Y(J-1)-Y(J-2))*YSF)
END DO
RETURN
END
!******************************************
! *
! SUBROTINA INICIAL *
! *
!******************************************
SUBROUTINE INICIAL(IMAX,JMAX,UP)
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
PARAMETER (NX=100,NY=100)
COMMON/PTN/ POT(NX,NY)
COMMON/GRID/ X(NX),Y(NY)
UP = 1.0D0
DO J=1,JMAX
DO I = 1,IMAX
POT(I,J)=UP*X(I)
END DO
END DO
RETURN
END
!******************************************
! *
! SUBROTINA CONTORNO *
! *
!******************************************
SUBROUTINE CONTORNO(IMAX,JMAX,UA,UB,UD,ILE,ITE,DY,t)
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
PARAMETER (NX=100, NY=100)
COMMON/GRID/ X(NX),Y(NY)
COMMON/PTN/ POT(NX,NY)
! Entrada e Saída
DO J=1,JMAX
POT(1,J)=UA*X(1)
POT(IMAX,J)=UB*X(IMAX)
END DO
! Fronteira Superior
DO I=1, IMAX
POT(I,JMAX)=UD*X(I)
END DO
!Simetria
DO I=1, IMAX
POT(I,1) = POT(I,2)
END DO
! Sobre o Corpo
DO I=ILE,ITE
POT(I,1) = POT(I,2) - 2.0D0*DY*UA*t*(1-(2.0D0*X(I)))
END DO
RETURN
END
!******************************************
! *
! SUBROTINA RESIDUO *
! *
!******************************************
SUBROUTINE RESIDUO(IMAX,JMAX,TESTE)
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
PARAMETER (NX=100, NY=100)
COMMON/RESI/ RE(NX,NY)
COMMON/GRID/ X(NX),Y(NY)
COMMON/PTN/ POT(NX,NY)
! CALCULO DO RESIDUO
DO J=2,JMAX-1
DO I=2,IMAX-1
RE(I,J) = ((2.0D0/((X(I+1))-(X(I-1))))*(((POT(I+1,J)-POT(I,J))/(X(I+1)-X(I)))-((POT(I,J)-POT(I-1,J))/(X(I)-X(I-1)))))+ &
&((2.0D0/((Y(J+1))-(Y(J-1))))*(((POT(I,J+1)-POT(I,J))/(Y(J+1)-Y(J)))-((POT(I,J)-POT(I,J-1))/(Y(J)-Y(J-1)))))
END DO
END DO
! CALCULO DO RESIDUO MAXIMO
TESTE=0.0D0
DO J=2,JMAX-1
DO I=2,IMAX-1
IF(DABS(RE(I,J)).GT.TESTE) THEN
TESTE=DABS(RE(I,J))
END IF
END DO
END DO
RETURN
END
!******************************************
! *
! SUBROTINA SOLVER *
! *
!******************************************
SUBROUTINE SOLVER(IMAX,JMAX,NMAX,PREC,N,NPR,DY,UA,UB,UD,ILE,ITE,t)
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
PARAMETER (NX=100,NY=100)
COMMON/GRID/ X(NX),Y(NY)
COMMON/RESI/ RE(NX,NY)
COMMON/NPJACO/ NPJ(NX,NY)
COMMON/CORREC/ C(NX,NY)
COMMON/PTN/ POT(NX,NY)
TESTE=100.0D0
N=1
IMP=NPR-1
OPEN(10,FILE='remax.dat')
! INICIO DAS ITERAÇÕES
CALL CONTORNO(IMAX,JMAX,UA,UB,UD,ILE,ITE,DY,t)
DO WHILE((N.NE.(NMAX+1)).AND.(TESTE.GT.PREC))
CALL RESIDUO(IMAX,JMAX,TESTE)
WRITE(*,*) N,TESTE
WRITE(10,*) N,TESTE
DO J=2,JMAX-1
DO I=2,IMAX-1
NPJ(I,J) = (((2.0D0)/((X(I+1))-(X(I-1))))*(-((1.0D0)/(X(I+1)-X(I)))-((1.0D0)/(X(I)-X(I-1)))))+ &
& (((2.0D0)/((Y(J+1))-(Y(J-1))))*(-((1.0D0)/(Y(J+1)-Y(J)))-((1.0D0)/(Y(J)-Y(J-1)))))
C(I,J) = -(RE(I,J))/NPJ(I,J)
POT(I,J) = POT(I,J)+C(I,J)
END DO
END DO
N=N+1
IMP=IMP+1
!==========================================================================================================
! SAÍDA DE RESULTADOS
IF(IMP.EQ.NPR) THEN
WRITE(4,10) IMAX,JMAX
10 FORMAT('TITLE = " Malha Cartesiana "',/,&
& 'VARIABLES = X, Y, POT, NPJ, RE',/,&
& 'ZONE T ="Zone-one", I=',I5,'J=',I5,',F=POINT')
DO J=1,JMAX
DO I=1,IMAX
WRITE(4,*) 'X',I,':', X(I),Y(J), POT(I,J), NPJ(I,J), RE(I,J)
END DO
END DO
IMP=0
END IF
!
END DO
! FIM DAS ITERAÇÕES
RETURN
END
您没有在代码中声明变量,而是依靠隐式类型。因此 NPJ 是一个整数数组。这是一个坏习惯。始终声明类型,并在每个程序单元中放入 IMPLICIT NONE。它可能需要更多编码,但这是值得的。
在对NPJ(I,J)的赋值中,如果右边较小,则截断为零[1]。由于此行后跟 C(I,J) = -(RE(I,J))/NPJ(I,J)
,因此除以零。
在您的情况下,NPJ 可能应该声明为双精度。但是我并没有调查太多它应该做什么。
[1] 更准确地说,双精度值(称为 A)的转换就像代码中存在 INT(A,K) 一样,其中 K 是 NPJ 的整数类型(此处应为默认整数).请参阅 Fortran 2008 标准的第 7.2.1.3 节#8。您会在 13.7.81 #5 节中发现当 |A|<1.
时 INT(A) 为零
我正在尝试 运行 geany 中的子例程,但它让我不断发出以下警告
NPJ(I,J) = DBLE(((2)/((X(I+1))-(X(I-1))))*DBLE(-((1)/(X(I+1)-X(I)))-((1)/(X(I)-
X(I-1)))))+ &
1
Warning: Possible change of value in conversion from REAL(8) to INTEGER(4) at (1)
代码后跟
C(I,J) = -(RE(I,J))/NPJ(I,J)
在下一行。
每次我 运行 它给出的程序都会被零除。
代码在这里:
! PROJETO 1 - MÉTODOS EXPERIMENTAIS EM HIDRODINÂMICA
!******************************************
! *
! PROGRAMA PRINCIPAL *
! *
!******************************************
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
Parameter (NX = 100, NY = 100)
! DECLARAÇÃO DE VARIÁVEIS
COMMON/GRID/X(NX),Y(NY)
COMMON/RESI/RE(NX,NY)
COMMON/PTN/ POT(NX,NY)
CHARACTER*30 BOBO
! DEFINIÇÃO DOS ARQUIVOS DE ENTRADA E SAÍDA
OPEN(3,FILE = 'placa.dat')
OPEN(4,FILE = 'output.dat')
! ENTRADA DE DADOS
READ(3,*) BOBO,IMAX
WRITE(*,'(A30,I10)')BOBO,IMAX
READ(3,*) BOBO,JMAX
WRITE(*,'(A30,I10)')BOBO,JMAX
READ(3,*) BOBO,t
WRITE(*,'(A30,F10.3)')BOBO,t
READ(3,*) BOBO,NMAX
WRITE(*,'(A30,I10)')BOBO,NMAX
READ(3,*) BOBO,UA
WRITE(*,'(A30,D10.3)')BOBO,UA
READ(3,*) BOBO,UB
WRITE(*,'(A30,D10.3)')BOBO,UB
READ(3,*) BOBO,UC
WRITE(*,'(A30,D10.3)')BOBO,UC
READ(3,*) BOBO,UD
WRITE(*,'(A30,D10.3)')BOBO,UD
READ(3,*) BOBO,UP
WRITE(*,'(A30,D10.3)')BOBO,UP
READ(3,*) BOBO,PREC
WRITE(*,'(A30,D10.3)')BOBO,PREC
READ(3,*) BOBO,NPR
WRITE(*,'(A30,I10)')BOBO,NPR
READ(3,*) BOBO,ITE
WRITE(*,'(A30,I10)')BOBO,ITE
READ(3,*) BOBO,ILE
WRITE(*,'(A30,I10)')BOBO,ILE
READ(3,*) BOBO,XSF
WRITE(*,'(A30,F10.3)')BOBO,XSF
READ(3,*) BOBO,YSF
WRITE(*,'(A30,F10.3)')BOBO,YSF
!$$$$$$
!$$$$$$ WRITE(*,*)"Os dados de entrada estao corretos?"
!$$$$$$ WRITE(*,*)"1--------SIM"
!$$$$$$ WRITE(*,*)"2--------NAO"
!$$$$$$ READ(*,*)INF
!$$$$$$ IF(INF.EQ.2) STOP
! GERAÇÃO DA MALHA COMPUTACIONAL
CALL MALHA(IMAX,JMAX,DX,ITE,ILE,XSF,YSF,DY)
! ! CONDIÇÃO INICIAL
CALL INICIAL(IMAX,JMAX,UP)
!!! INÍCIO DAS ITERAÇÕES
CALL SOLVER(IMAX,JMAX,NMAX,PREC,N,NPR,DY,UA,UB,UD,ILE,ITE,t)
!! FIM DA EXECUÇÃO
STOP
END
!******************************************
! *
! SUBROTINA MALHA *
! *
!******************************************
SUBROUTINE MALHA(IMAX,JMAX,DX,ITE,ILE,XSF,YSF,DY)
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
PARAMETER (NX=100,NY=100)
COMMON/GRID/ X(NX),Y(NY)
DX=1.0D0/DBLE(ITE-ILE)
DO I=ILE,ITE
X(I)=DX*DBLE(I-ILE)
END DO
DO I=ITE,IMAX
X(I)=X(I-1)+((X(I-1)-X(I-2))*XSF)
END DO
DO I=ILE-1,1,-1
X(I)=X(I+1)+((X(I+1)-X(I+2))*XSF)
END DO
Y(1) = (-DX)/2.0D0
Y(2) = DX/2.0D0
DY = Y(2)-Y(1)
DO J=3, JMAX
Y(J)=Y(J-1)+((Y(J-1)-Y(J-2))*YSF)
END DO
RETURN
END
!******************************************
! *
! SUBROTINA INICIAL *
! *
!******************************************
SUBROUTINE INICIAL(IMAX,JMAX,UP)
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
PARAMETER (NX=100,NY=100)
COMMON/PTN/ POT(NX,NY)
COMMON/GRID/ X(NX),Y(NY)
UP = 1.0D0
DO J=1,JMAX
DO I = 1,IMAX
POT(I,J)=UP*X(I)
END DO
END DO
RETURN
END
!******************************************
! *
! SUBROTINA CONTORNO *
! *
!******************************************
SUBROUTINE CONTORNO(IMAX,JMAX,UA,UB,UD,ILE,ITE,DY,t)
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
PARAMETER (NX=100, NY=100)
COMMON/GRID/ X(NX),Y(NY)
COMMON/PTN/ POT(NX,NY)
! Entrada e Saída
DO J=1,JMAX
POT(1,J)=UA*X(1)
POT(IMAX,J)=UB*X(IMAX)
END DO
! Fronteira Superior
DO I=1, IMAX
POT(I,JMAX)=UD*X(I)
END DO
!Simetria
DO I=1, IMAX
POT(I,1) = POT(I,2)
END DO
! Sobre o Corpo
DO I=ILE,ITE
POT(I,1) = POT(I,2) - 2.0D0*DY*UA*t*(1-(2.0D0*X(I)))
END DO
RETURN
END
!******************************************
! *
! SUBROTINA RESIDUO *
! *
!******************************************
SUBROUTINE RESIDUO(IMAX,JMAX,TESTE)
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
PARAMETER (NX=100, NY=100)
COMMON/RESI/ RE(NX,NY)
COMMON/GRID/ X(NX),Y(NY)
COMMON/PTN/ POT(NX,NY)
! CALCULO DO RESIDUO
DO J=2,JMAX-1
DO I=2,IMAX-1
RE(I,J) = ((2.0D0/((X(I+1))-(X(I-1))))*(((POT(I+1,J)-POT(I,J))/(X(I+1)-X(I)))-((POT(I,J)-POT(I-1,J))/(X(I)-X(I-1)))))+ &
&((2.0D0/((Y(J+1))-(Y(J-1))))*(((POT(I,J+1)-POT(I,J))/(Y(J+1)-Y(J)))-((POT(I,J)-POT(I,J-1))/(Y(J)-Y(J-1)))))
END DO
END DO
! CALCULO DO RESIDUO MAXIMO
TESTE=0.0D0
DO J=2,JMAX-1
DO I=2,IMAX-1
IF(DABS(RE(I,J)).GT.TESTE) THEN
TESTE=DABS(RE(I,J))
END IF
END DO
END DO
RETURN
END
!******************************************
! *
! SUBROTINA SOLVER *
! *
!******************************************
SUBROUTINE SOLVER(IMAX,JMAX,NMAX,PREC,N,NPR,DY,UA,UB,UD,ILE,ITE,t)
IMPLICIT DOUBLE PRECISION (A-H,O-Z)
PARAMETER (NX=100,NY=100)
COMMON/GRID/ X(NX),Y(NY)
COMMON/RESI/ RE(NX,NY)
COMMON/NPJACO/ NPJ(NX,NY)
COMMON/CORREC/ C(NX,NY)
COMMON/PTN/ POT(NX,NY)
TESTE=100.0D0
N=1
IMP=NPR-1
OPEN(10,FILE='remax.dat')
! INICIO DAS ITERAÇÕES
CALL CONTORNO(IMAX,JMAX,UA,UB,UD,ILE,ITE,DY,t)
DO WHILE((N.NE.(NMAX+1)).AND.(TESTE.GT.PREC))
CALL RESIDUO(IMAX,JMAX,TESTE)
WRITE(*,*) N,TESTE
WRITE(10,*) N,TESTE
DO J=2,JMAX-1
DO I=2,IMAX-1
NPJ(I,J) = (((2.0D0)/((X(I+1))-(X(I-1))))*(-((1.0D0)/(X(I+1)-X(I)))-((1.0D0)/(X(I)-X(I-1)))))+ &
& (((2.0D0)/((Y(J+1))-(Y(J-1))))*(-((1.0D0)/(Y(J+1)-Y(J)))-((1.0D0)/(Y(J)-Y(J-1)))))
C(I,J) = -(RE(I,J))/NPJ(I,J)
POT(I,J) = POT(I,J)+C(I,J)
END DO
END DO
N=N+1
IMP=IMP+1
!==========================================================================================================
! SAÍDA DE RESULTADOS
IF(IMP.EQ.NPR) THEN
WRITE(4,10) IMAX,JMAX
10 FORMAT('TITLE = " Malha Cartesiana "',/,&
& 'VARIABLES = X, Y, POT, NPJ, RE',/,&
& 'ZONE T ="Zone-one", I=',I5,'J=',I5,',F=POINT')
DO J=1,JMAX
DO I=1,IMAX
WRITE(4,*) 'X',I,':', X(I),Y(J), POT(I,J), NPJ(I,J), RE(I,J)
END DO
END DO
IMP=0
END IF
!
END DO
! FIM DAS ITERAÇÕES
RETURN
END
您没有在代码中声明变量,而是依靠隐式类型。因此 NPJ 是一个整数数组。这是一个坏习惯。始终声明类型,并在每个程序单元中放入 IMPLICIT NONE。它可能需要更多编码,但这是值得的。
在对NPJ(I,J)的赋值中,如果右边较小,则截断为零[1]。由于此行后跟 C(I,J) = -(RE(I,J))/NPJ(I,J)
,因此除以零。
在您的情况下,NPJ 可能应该声明为双精度。但是我并没有调查太多它应该做什么。
[1] 更准确地说,双精度值(称为 A)的转换就像代码中存在 INT(A,K) 一样,其中 K 是 NPJ 的整数类型(此处应为默认整数).请参阅 Fortran 2008 标准的第 7.2.1.3 节#8。您会在 13.7.81 #5 节中发现当 |A|<1.
时 INT(A) 为零