如何在 while 循环中更改 fortran 程序索引变量?
How to alter a fortran program index variable in a while loop?
我有以下代码:
PROGRAM PEU72
USE PRIMES
IMPLICIT NONE
INTEGER, PARAMETER :: MYKIND = SELECTED_INT_KIND(16)
INTEGER (KIND=MYKIND) :: SOFAR
INTEGER :: NRP, M
SOFAR = 0_MYKIND
CALL GEN(ALLNUMS,ALLPRIMES) ! This is a call to a module that creates a list of primes. It works fine.
DO M = 2,8 ! When I try to compile in G95, this loop doesn't increment. M = 2 for each cycle.
SOFAR = SOFAR + NRP(M)
END DO
PRINT *,'ANS: ',SOFAR
READ *,SOFAR
END PROGRAM PEU72
FUNCTION NRP(NUM) RESULT(PHI)
USE PRIMES
IMPLICIT NONE
INTEGER :: NUM, PHI, I!, DIF
INTEGER :: VAR
I = 1
PHI = NUM-1
VAR = NUM
DO
IF (MOD(NUM,ALLPRIMES(I))==0) THEN
PHI = PHI-((NUM-1)/ALLPRIMES(I))
NUM = NUM/ALLPRIMES(I) ! This is the line that silverfrost doesn't like. The code works absolutely fine without it, it just takes too long.
END IF
I = I + 1
VAR = NUM-ALLPRIMES(I)
IF (VAR<0) THEN
EXIT
END IF
END DO
RETURN
END FUNCTION
出于优化目的,我想在每次迭代时除以 num,这是 while 循环的一个条件。当我这样做时,我的 (silverfrost) 编译器抛出一个错误(Active DO loop altered),而 G95 编译器
完全中断,根本不迭代第一个循环。我试过使用 DO - IF - EXIT 术语,none 有效。如何实现每次除Num,Allprimes(i)递增的情况?
行中
NUM = NUM/ALLPRIMES(I)
您正在更改 NUM
,其中输入 NRP
作为参数。 NRP
的调用给出了 M
所以实际上你正在改变 M
.
Fortran 默认通过引用传递参数。 (以及@francescalus 评论的空中碰撞:"there is an attempt to modify the loop variable m (as the actual argument associated with num) inside the loop. This is not allowed.")。
所以你必须根据问题改变你的 for 循环或在你的例程中重新定义 NUM
。
对于方便操作循环计数器的情况,我建议您使用另一种方法(相同的逻辑但符合标准):
M = 2
DO WHILE(M <= 8)
SOFAR = SOFAR + NRP(M)
M = M + 1 ! if you need to increment the index
END DO
编辑:
How to alter a fortran program index variable in a while loop?
再看题名,我觉得这不是替代,而是字面上的回答。
我有以下代码:
PROGRAM PEU72
USE PRIMES
IMPLICIT NONE
INTEGER, PARAMETER :: MYKIND = SELECTED_INT_KIND(16)
INTEGER (KIND=MYKIND) :: SOFAR
INTEGER :: NRP, M
SOFAR = 0_MYKIND
CALL GEN(ALLNUMS,ALLPRIMES) ! This is a call to a module that creates a list of primes. It works fine.
DO M = 2,8 ! When I try to compile in G95, this loop doesn't increment. M = 2 for each cycle.
SOFAR = SOFAR + NRP(M)
END DO
PRINT *,'ANS: ',SOFAR
READ *,SOFAR
END PROGRAM PEU72
FUNCTION NRP(NUM) RESULT(PHI)
USE PRIMES
IMPLICIT NONE
INTEGER :: NUM, PHI, I!, DIF
INTEGER :: VAR
I = 1
PHI = NUM-1
VAR = NUM
DO
IF (MOD(NUM,ALLPRIMES(I))==0) THEN
PHI = PHI-((NUM-1)/ALLPRIMES(I))
NUM = NUM/ALLPRIMES(I) ! This is the line that silverfrost doesn't like. The code works absolutely fine without it, it just takes too long.
END IF
I = I + 1
VAR = NUM-ALLPRIMES(I)
IF (VAR<0) THEN
EXIT
END IF
END DO
RETURN
END FUNCTION
出于优化目的,我想在每次迭代时除以 num,这是 while 循环的一个条件。当我这样做时,我的 (silverfrost) 编译器抛出一个错误(Active DO loop altered),而 G95 编译器 完全中断,根本不迭代第一个循环。我试过使用 DO - IF - EXIT 术语,none 有效。如何实现每次除Num,Allprimes(i)递增的情况?
行中
NUM = NUM/ALLPRIMES(I)
您正在更改 NUM
,其中输入 NRP
作为参数。 NRP
的调用给出了 M
所以实际上你正在改变 M
.
Fortran 默认通过引用传递参数。 (以及@francescalus 评论的空中碰撞:"there is an attempt to modify the loop variable m (as the actual argument associated with num) inside the loop. This is not allowed.")。
所以你必须根据问题改变你的 for 循环或在你的例程中重新定义 NUM
。
对于方便操作循环计数器的情况,我建议您使用另一种方法(相同的逻辑但符合标准):
M = 2
DO WHILE(M <= 8)
SOFAR = SOFAR + NRP(M)
M = M + 1 ! if you need to increment the index
END DO
编辑:
How to alter a fortran program index variable in a while loop?
再看题名,我觉得这不是替代,而是字面上的回答。