Ошибка: запятая требуется после дескриптора P в строке формата - PullRequest
0 голосов
/ 01 марта 2019

Когда я пытаюсь скомпилировать calrank.for (CALRANK_v7.0.0_L140912.zip) с помощью gfortran, я получаю эту ошибку:

> gfortran  -m64 -c -o calrank.o calrank.for
calrank.for:1922:32:
         write(io,'(2f10.3,1p1000(2x,e16.7,1x,2a10,1x))')
                                1
Error: Comma required after P descriptor in format string at (1)

При вводе запятой я получаю ту же ошибку.
Iобратите внимание только на то, что код был скомпилирован ранее с помощью LF95.

   subroutine xycout(io,nrank,nsp)
      use userinf
      use header
      use rankdata

      implicit none

    integer :: io,nrank,nsp
      integer :: k,ir,is,i
      character(len=20)   :: head1,head2,head3
      character(len=40)   :: add1x,add2x,add3x
      character(len=40)   :: add1(nsp),add2(nsp)
      character(len=40)   :: add3(nsp)
 ......
 c --- Loop over receptors to write data records
      do ir=1,ntotrec(k)
         write(io,'(2f10.3,1p1000(2x,e16.7,1x,2a10,1x))')
     &                   xreckm(ir,k),yreckm(ir,k),
     &                  (xounit(is,k)*rankvalue(ir,is,nrank),
     &                   arankdate(ir,is,nrank),
     &                   aranktime(ir,is,nrank),is=1,nspout(k))
      enddo

      return
      end

Некоторые переменные определены в другом месте кода как:

c --- Real arrays for header (derived)
      allocate (xreckm(mxrec,k),yreckm(mxrec,k))
c --- Modified units multiplier
      allocate (xounit(mxspout,k))
      c --- Array of values (all species, receptors) for requested ranks
      allocate (rankvalue(ntotrec(k),nspout(k),n_ranks))
      allocate (arankdate(ntotrec(k),nspout(k),n_ranks))
      allocate (aranktime(ntotrec(k),nspout(k),n_ranks))
c --- Integer arrays for header
      deallocate (ndrec,nctrec,nspout,i2dmet,iutmzn)

Ответы [ 2 ]

0 голосов
/ 02 марта 2019

@ francescalus предложил расширить мой комментарий.

Во-первых, Фортрану обычно требуется запятая между двумя "элементами формата".Элементом формата является дескриптор редактирования (F, E и т. Д.) С или без счетчика повторений, предшествующий ему, или группа элементов формата, заключенная в скобки (которая может иметь собственный счетчик повторений; @Vladimir F, упомянутый * - это "неограниченное количество повторений »и может использоваться только с группой в скобках.

Запятая может быть опущена:

  • между дескриптором редактирования P и сразу после F, E, EN,Дескриптор редактирования ES, EX, D или G, которому, возможно, предшествует повторяющаяся спецификация,
  • перед дескриптором редактирования косой черты, когда необязательная спецификация повтора не появляется,
  • после дескриптора редактирования косой черты,или
  • до или после дескриптора редактирования двоеточия

Теперь, что касается дескриптора редактирования P, это устанавливает масштабный коэффициент, и это действительно странно и имеет очень разные эффекты в зависимости от того, какого родаредактирования, который вы делаете. Он также «липкий» и применяется ко всем последующим изменениям в этом формате.

При вводе это приводит к тому, что значение чтения делится на10 ** k, где k - масштабный коэффициент (2P означает k = 2 и т. Д.).Таким образом, если символы на входе 123 и 2P действует, значение читается как 1.23.Точно так же, если бы действовал -2P, 123 читалось бы как 12300. Десятичная точка на входе не меняет это, но показатель степени удаляет масштабирование.Таким образом, значение 1,23, считанное с 2P, равно 0,0123, но 1,23E0 равно 1,23.

При выводе с редактированием F выходное значение умножается на 10 ** k, изменяя схему ввода.

Вы можете спросить, ПОЧЕМУ ???Ответ заключается в перфокартах, форме ввода (а иногда и вывода), используемой в 1950-х - 70-х годах.У них было 80 столбцов и тратить столбец на десятичную точку может быть проблемой.Таким образом, коэффициент масштабирования позволил опустить десятичную точку, но все равно получить дроби.

Но подождите, это становится более странным!При выводе с редактированием E и D масштабный коэффициент просто определяет количество начальных цифр слева от десятичной точки (и последующее уменьшение показателя степени. Таким образом, для значения 1,23 и формата 2P, E11.3,вы получите b12.300E-01 (b = пусто, если SP не действует, что является ответом для другого дня.)

А для вывода в формате G? Даже страннее. Если значение находится вВ диапазоне, где вы получаете эквивалент формата F, коэффициент масштабирования не действует, в противном случае он ведет себя как E.

Наконец, коэффициент масштабирования не влияет на редактирование EN, ES или EX. (EX? ЭтоФункция F2018 для шестнадцатеричного вывода с плавающей запятой.)

Одно хорошее использование формата P - это когда вычисления в валюте с целыми числами вместо действительных значений, поскольку последний может потерять точность (например, .01 не имеет точного двоичного числа с плавающей запятой)представление.) Предполагая, что значения, с которыми вы имеете дело, не слишком велики, вы можете читать доллары и центы в целое число в формате -2P и не терять ни копейки, делая рекламуделение, вычитание и умножение.Однажды я написал точный калькулятор ипотеки.

0 голосов
/ 01 марта 2019

Вы должны сделать именно то, что говорится в сообщении об ошибке, поставить запятую после дескриптора p:

write(io,'(2f10.3,1p,1000(2x,e16.7,1x,2a10,1x))')

Если вы не знаете, что такое дескриптор ap, см., Например, https://docs.oracle.com/cd/E19957-01/805-4939/z4000743a6e2/index.html или любой учебник о дескрипторах редактирования Fortran.Как Стивен Лайонел комментирует ниже, вы можете использовать дескриптор p без запятой перед обычными дескрипторами редактирования данных.

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