Как изменить переменную индекса программы Fortran в цикле while? - PullRequest
0 голосов
/ 09 сентября 2018

У меня есть следующий код:

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) компилятор выдает ошибку (активный цикл DO изменен), когда я делаю это, и компилятор G95 полностью разрывается, вообще не повторяя первый цикл. Я пытался использовать терминологию DO - IF - EXIT, ни одна из них не работает. Как мне добиться ситуации, когда Num делится каждый раз, а Allprimes (i) увеличивается?

Ответы [ 2 ]

0 голосов
/ 09 сентября 2018

Я предлагаю вам альтернативный подход (та же логика, но соответствует стандарту), для случаев, когда удобно манипулировать счетчиком цикла:

M = 2
DO WHILE(M <= 8)
  SOFAR = SOFAR + NRP(M)
  M = M + 1 ! if you need to increment the index
END DO

Edit:

Как изменить переменную индекса программы на фортране в цикле while?

Снова прочитав название вопроса, я думаю, что это не альтернатива , а буквальный ответ.

0 голосов
/ 09 сентября 2018

В строке

NUM = NUM/ALLPRIMES(I) вы изменяете NUM, который вводит NRP в качестве аргумента. Вызов NRP дает его как M, так что на самом деле вы меняете M.

Фортран передает аргументы по умолчанию по ссылке. (и в результате воздушного столкновения комментария @francescalus: «попытка изменить переменную цикла m (как фактический аргумент, связанный с num) внутри цикла. Это недопустимо.»).

Таким образом, вы должны изменить цикл for или переопределить NUM в своей программе, в зависимости от проблемы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...