我有以下代码:
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循环已更改),并且G95编译器完全中断,而不是完全迭代第一个循环。我尝试过使用DO - IF - EXIT术语,但没有一个可行。我怎样才能实现Num每次都被分割的情况,Allprimes(i)会增加?
在线
NUM = NUM/ALLPRIMES(I)
你改变NUM
进入NRP
作为参数。 NRP
的召唤使它成为M
所以实际上你正在改变M
。
Fortran默认通过引用传递参数。 (并且通过@francescalus评论的空中碰撞:“试图在循环内修改循环变量m(作为与num相关联的实际参数)。这是不允许的。”)。
因此,您必须根据问题改变您的for循环或重新定义常规中的NUM
。
我建议你采用另一种方法(相同的逻辑但符合标准),对于操作循环计数器很方便的情况:
M = 2
DO WHILE(M <= 8)
SOFAR = SOFAR + NRP(M)
M = M + 1 ! if you need to increment the index
END DO
编辑:
如何在while循环中更改fortran程序索引变量?
再次阅读问题的标题,我认为这不是另类,而是一个字面的答案。