современный фортран , Бортеньев. О. В. Бартеньев Современный Фортран
Скачать 2.24 Mb.
|
307 О. В. Бартеньев. Современный ФОРТРАН Дескриптор преобразования вещественных чисел Ew.d[Ee] требует, чтобы при выводе ассоциируемый с дескриптором Е элемент имел вещественный тип одиночной или двойной точности. При вводе входное поле идентично входному полю дескриптора F. Параметр е дескриптора E при вводе игнорируется. Форма выходного поля зависит от задаваемого дескриптором kP коэффициента масштабирования. При равном нулю коэффициенте масштабирования (задается по умолчанию) выходное поле, длина которого равна w, представляет собой: знак минус (в случае отрицательного числа), далее десятичная точка, затем строка из d цифр, затем поле под десятичную экспоненту, имеющее одну из показанных в табл. 9.3 форм. Таблица 9.3. Форма поля под десятичную экспоненту в дескрипторе Е Дескриптор Показатель степени экспоненты Форма поля Ew.d |p| ≤ 99 E, затем плюс или минус, затем показатель степени десятичной экспоненты из двух цифр Ew.d 99 < |p| ≤ 999 Плюс или минус, затем показатель степени десятичной экспоненты из трех цифр Ew.dEe |p| ≤ 10 e - 1 E, затем плюс или минус, затем показатель степени десятичной экспоненты из е цифр, который может содержать и ведущие нули Пример: real(8) :: a = 1.23D+205 real(4) :: b = -.0000123445, c = -.123445 write(*, '(E15.8)') a ! .12300000+206 write(*, '(1x,2E12.5)') b, c ! -.12344E-04 -.12344E+00 write(*, '(1x,2E14.5E4)') b, c ! -.12344E-0004 -.12344E+0000 Рассмотрим механизм преобразования числа 1.23 при выводе на примере дескриптора E11.5, т. е. результат выполнения оператора write(*, '(e11.5)') 1.23 ! .12300E+01 Число 1.23 расположится на поле длиной в 11 символов. Последние 4 символа в дескрипторе Е отводятся для обозначения десятичной экспоненты (Е), знака и показателя степени. При выводе все цифры отображаются после десятичной точки, т. е. на выходе мы получим число 0.123*10 1 . Поскольку в дескрипторе после десятичной точки предусмотрено 5 символов (d = 5), то после вывода .123 будут добавлены два нуля, а затем уже последует десятичная экспонента E+01. Результатом преобразований будет строка .12300E+01. 308 9. Форматный ввод/вывод Дескриптор kP с дескриптором Ew.d[Ee] работает так: • если масштабный коэффициент k больше -d и k ≤0 (-d < k ≤ 0), то выходное поле содержит k ведущих нулей после десятичной точки и d+k значащих цифр после них; • если 0 < k < d + 2, то выходное поле содержит k значащих цифр слева от десятичной точки и d - k - 1 цифр будут расположены после десятичной точки. Другие значения k недопустимы, например: real :: b = -.0000123445, c = -.123445 write(*, '(1x, 2PE12.5)') b ! -12.3445E-06 write(*, '(1x, -2PE12.5)') c ! -.00123E+02 Дескриптор ENw.d[Ee] передает данные в инженерном формате и работает так же, как и дескриптор E, за тем исключением, что при выводе абсолютное значение неэкспоненциальной части всегда находится в диапазоне от 1 до 1000. Показатель степени экспоненты при работе с дескриптором EN всегда кратен трем. Форма поля под экспоненту в дескрипторе EN такая же, как и для дескриптора E, например: real :: x = -12345.678, y = 0.456789, z = 7.89123e+23 write(*, 1) x, z !-12.34568E+03 789.12300E+21 1 format (1x, en13.5, 1x, en13.5) write(*, 2) y, z ! 456.79e-0003 789.12e+0021 2 format (1x, en13.2e4, 1x, en13.2e4) Дескриптор ESw.d[Ee] обеспечивает передачу данных в научном формате и работает так же, как и дескриптор E, за тем исключением, что при выводе абсолютное значение неэкспоненциальной части всегда находится в диапазоне от 1 до 10. Форма поля под экспоненту при работе с ES такая же, как и для дескриптора E. real :: x = -12345.678, y = 0.456789, z = 7.89123e+23 write(*, 1) x, z ! -1.23457E+04 7.89123E+23 1 format (1x, es13.5, 1x, es13.5) write(*, 2) y, z ! 4.57E-0001 7.89E+0023 2 format (1x, es13.2e4, 1x, es13.2e4) Элементы списка вывода, ассоциируемые с дескриптором преобразования двойной точности Dw.d, должны иметь вещественный тип одиночной или двойной точности. Все правила и параметры, применимые к дескриптору Е, также применимы и к дескриптору D. Входные поля при работе с дескриптором D формируются так же, как и входные поля для дескриптора F, с теми же значениями параметров w и d. Форма выходного поля зависит от масштабного коэффициента, задаваемого дескриптором kР. При равном нулю коэффициенте масштабирования выходное поле выглядит так: знак минус (в случае вывода отрицательного числа), затем десятичная точка, затем строка цифр 309 О. В. Бартеньев. Современный ФОРТРАН и, наконец, поле под десятичную экспоненту. Последнее поле формируется по одному из указанных в табл. 9.4 правил. Таблица 9.4. Форма поля под десятичную экспоненту в дескрипторе D Дескриптор Показатель степени экспоненты Форма поля Dw.d |p| ≤ 99 D, затем плюс или минус, затем показатель степени десятичной экспоненты из двух цифр Dw.d 99 < |p| ≤ 999 Плюс или минус, затем показатель степени десятичной экспоненты из трех цифр Масштабирование при работе с дескриптором D выполняется по тем же правилам, по которым оно выполняется и для дескриптора Е. Пример: real(8) :: b = -.0000123445_8 write(*, '(1x, D12.5)') b ! -.12344D-04 write(*, '(1x, 2PD12.5)') b ! -12.3445D-06 write(*, '(1x,-2PD12.5)') b ! -.00123D-02 При передаче данных логического типа используется дескриптор Lw. Если ассоциируемый в списке вывода с дескриптором L элемент не является элементом логического типа, то возникнет ошибка исполнения. В результате преобразования значения логического типа будет выведено: w - 1 пробелов, а затем T или F. Поле ввода, так же как и поле вывода, имеет длину в w символов и может содержать пробелы, затем необязательную десятичную точку, затем Т (t) для задания истина или F (f) для задания ложь. Любые последующие символы в поле ввода игнорируются. Поэтому на входе может быть задано и .TRUE. и .FALSE. Пример: logical :: fl = .true., yesno = .false. write(*, '(1X, 2L5)') fl, yesno ! T F Дескриптор A[w] используется преимущественно при В/В данных символьного типа. Если длина w опущена, то она принимается равной длине ассоциируемого с дескриптором А элемента В/В. Элемент списка В/В может быть любого типа. Если он не является элементом символьного типа, то каждому байту внутреннего представления ставится в соответствие символ. Например, элементу типа INTEGER(2) соответствует 2 символа. Однако независимо от используемого типа данных каждый элемент списка В/В должен быть задан как последовательность символов. 310 9. Форматный ввод/вывод Когда элемент списка В/В имеет тип INTEGER, REAL или LOGICAL, то для задания строк символов можно использовать холлеритовские символьные константы. Для каждого типа данных сохраняется возможность использования встроенных для данного типа операций. Так, объявленные в INTEGER строки символов можно складывать, перемножать и т. д. Входная строка текста вводится посимвольно с последующим преобразованием символа в его двоичное представление. Если при вводе число символов элемента k < w, то будет введено w символов, но только k последних будут принадлежать элементу ввода. Если k > w, то будет введено w символов, а оставшиеся символы строки будут заполнены завершающими пробелами. Выводимые с применением дескриптора А данные выравниваются по правой границе поля, завершающие пробелы сохраняются. Пример: integer(4) :: b = '2bcd7', g = 4Ha25f real(8) :: d = '#456&7xz' character(12) :: st1 = 'string 1', st2 = 10hNew string, st3*6 write(*, '(4(1x, A))') b, g + 2, d !2bcd c25f #456&7xz write(*, '(4(1x, A))') b - g ! -/._ write(*,'(1x, a14, a5)') st1, st2 ! string 1 New s read(*, '(A3)') st3 !ert - строка ввода (k > w) write(*, *) st3, 's' !ert s read(*, '(A8)') st3 !ert - строка ввода (k < w) write(*, *) st3, 's' !t s Пояснение. Переменная b занимает в памяти ЭВМ 4 байта, поэтому из строки '2bcd7' в b будет установлено только 4 первых ее символа. Обобщающий дескриптор Gw.d[Ee] может быть использован с данными любого встроенного типа. Для целочисленных данных дескриптор Gw.d имеет такое же действие, как и дескриптор Iw.m. Для логических данных Gw.d действует так же, как и Lw. Для символьных данных Gw.d действует так же, как и Aw. Пример: integer(4) :: k = 355 logical :: fl = .true. character(10) :: st = ' string' write(*, '(1x, 3g10.5)') k, fl, st ! 00355 T string Для вещественных данных дескриптор Gw.d[Ee] более гибок, чем дескриптор F, поскольку автоматически переключается с формата F на формат E в зависимости от величины передаваемых данных. Когда Gw.d[Ee] используется как вещественный дескриптор, поле ввода равно w символам и d символов на этом поле отводятся под следующие за десятичной точкой числа, т. е. при вводе Gw.d[Ee] работает так же, как 311 О. В. Бартеньев. Современный ФОРТРАН и Fw.d. При выводе преобразование G в зависимости от значения выводимой величины соответствует либо F-, либо Е-преобразованию. В табл. 9.5, 9.6 приведена интерпретация дескрипторов G и GE при выводе. Таблица 9.5. Интерпретация дескриптора Gw.d при выводе Абсолютное значение величины Интерпретация x < 0.1 Gw.d = Ew.d 0.1 ≤ x < 1 Gw.d = F(w - 4).d, 4( ) 1 ≤ x < 10 Gw.d = F(w - 4).(d - 1), 4( ) 10 d-2 ≤ x < 10 d-1 Gw.d = F(w - 4).1, 4( ) 10 d-1 ≤ x < 10 d Gw.d = F(w - 4).0, 4( ) 10 d ≤ x Gw.d = Ew.d Дескриптор Gw.d[De] эквивалентен дескриптору Gw.d[Ee] за тем исключением, что при выводе вместо E печатается D. Таблица 9.6. Интерпретация дескриптора Gw.dEe при выводе Абсолютное значение величины Интерпретация x < 0.1 Gw.dEe = Ew.d 0.1 ≤ x < 1 Gw.dEe = F(w - e - 2).d, (e + 2)( ) 1 ≤ x < 10 Gw.dEe = F(w-e-2).(d-1),(e+2)( ) 10 d-2 ≤ x < 10 d-1 Gw.dEe = F(w - e - 2).1, (e + 2)( ) 10 d-1 ≤ x < 10 d Gw.dEe = F(w - e - 2).0, (e + 2)( ) 10 d ≤ x Gw.dEe = Ew.d Пример: real :: b1 = .01234, b2 = 123400, b3 = 123.4 write(*, 1) b1, b2, b3 ! -.12340E-01 .12340E+06 123.40 write(*, 2) b1, b2, b3 ! -.12340E-001 .12340E+006 123.40 1 format(1x, 3G12.5) 2 format(1x, 3G12.5E3) 9.8. Дескрипторы управления Дескрипторы управления также называют неповторяющимися дескрипторами преобразований (ДП), поскольку перед такими дескрипторами (если только дескриптор не заключен в скобки) в спецификации формата нельзя указать коэффициент повторения. Неповторяющиеся ДП служат: • для управления позицией В/В (преобразования nХ, T, TL, TR); 312 9. Форматный ввод/вывод • внесения в запись дополнительной информации (преобразования апострофа и Холлерита); • масштабирования данных и других, приведенных в табл. 9.7, функций управления В/В. В списке ДП для разделения его отдельных дескрипторов используется запятая, которая может быть опущена: • между дескриптором P и сразу следующими за ним дескрипторами F, E, EN, ES, D или G, например: 1X, 2P F9.6; • перед или после дескрипторов апострофа ('), кавычек ("), обратного слеша (\) или двоеточия (:), например: 1x, I3, ' ' B8 \; • перед и после слеша, например: 1x, 2I5, 2(/ 2F5.2). Таблица 9.7. Неповторяющиеся дескрипторы преобразований Формы Имя Назначение Использование Строка Преобразование апострофа Передает строку текста в файл Вывод nH Преобразование Холлерита Передает n символов в файл " Q Преобразование опроса Возвращает число непрочитанных символов записи Ввод Tn, TLn, TRn Преобразование позиции Спецификация позиции в записи В/В nX Преобразование позиции " " " " " SP, SS, S Преобразование знака плюс Управление выводом знака плюс Вывод / Преобразование слеша Переход к следующей записи и простановка символов конца записи В/В \ Преобразование обратного слеша Продолжение текущей записи (для тех же целей можно использовать знак $) Вывод : Прерывание выполнения действия ДП При исчерпании списка вывода прерывает выполнение ДП " kP Преобразование масштабного коэффициента Устанавливает значение показателя степени в ДД F, E, D и G В/В BN, BZ Интерпретация пробела Устанавливает способ интерпретации пробелов Ввод 313 О. В. Бартеньев. Современный ФОРТРАН Преобразование апострофа или двойных кавычек выполняет вывод заключенной в апострофы или кавычки строки. Для вывода обрамленной апострофами и содержащей апострофы строки необходимо указать каждый выводимый апостроф дважды (либо заключить строку в двойные кавычки). Аналогично выполняется вывод содержащих двойные кавычки строк. Преобразование апострофа и двойных кавычек не может быть использовано с оператором READ. Пример: write(*, 1) 1 format(2x, 'Введите границы отрезка [a, b]: ') ! или write(*, '(2x, "Введите границы отрезка [a, b]: ")') ! или, применив дескриптор A write(*, '(2x, a)') 'Введите границы отрезка [a, b]: ' read(*, *) a, b Замечание. Если в спецификации формата оператора WRITE выводимая строка заключена в апострофы, то сама спецификация должна быть заключена в двойные кавычки; можно сделать наоборот, например: write(*, "(2x, 'Введите границы отрезка [a, b]: ')") Преобразование Холлерита. Дескриптор nH передает n символов, включая пробелы, в файл или на экран. Число символов, следующих за дескриптором nH, должно быть равно n. Преобразование Холлерита может быть использовано везде, где допустимо применение символьных констант. Принято называть константы, определенные при помощи дескриптора nH, холлеритовскими константами. Пример: write(*, 1) 1 format(2x, 31HВведите границы отрезка [a, b]:) ! или write(*, '(2x, 31HВведите границы отрезка [a, b]:)') Замечание. Фортран 95 удалил холлеритовские константы из стандарта; несмотря на это, они продолжают поддерживаться CVF. Преобразование опроса. Дескриптор Q возвращает число непереданных символов записи. Соответствующий дескриптору Q элемент списка В/В должен быть целого или логического типа. В следующем примере дескриптору Q соответствует переменная nq, в которую благодаря дескриптору Q будет считано (после ввода пяти элементов массива kar) число непереданных символов записи. Затем значение nq будет использовано при вводе массива chr. 314 9. Форматный ввод/вывод integer kar(5), nq character(1) chr(80) read(4, '(5I4, Q, 80A1)') kar, nq, (chr(i), i= 1, min(nq, 80)) Возвращаемое дескриптором Q значение можно использовать не только в текущем, но и в следующем операторе ввода. Для этого после опроса записи надо остаться в текущей записи, т. е. применить ввод без продвижения, например: integer k, nq ! Спецификатор ADVANCE = 'NO' задает ввод character(1) chr(80) ! без продвижения read(*, '(I2, Q)', advance = 'no') k, nq read(*, '(80A1)') (chr(i), i= 1, min(nq, 80)) Преобразование позиции. Дескрипторы T, TL и TR задают позицию записи, в которую или из которой будет передаваться следующий символ. Новая позиция может быть задана как левее, так и правее текущей. Это позволяет при вводе использовать запись более одного раза. Правда, не рекомендуется перемещаться в обратном направлении более чем на 512 байт (символов). Дескриптор Tn задает абсолютную табуляцию: передача следующего символа будет выполняться начиная с позиции n (отсчет позиций выполняется от начала записи). Дескриптор TRn задает относительную правую табуляцию: передача следующего символа будет выполняться начиная с позиции, расположенной на n символов правее текущей позиции. Дескриптор TLn задает относительную левую табуляцию: передача следующего символа будет выполняться начиная с позиции, расположенной на n символов левее текущей позиции. Если задаваемая дескриптором TLn позиция оказывается перед первой позицией текущей записи, то передача следующего символа будет выполняться с первой позиции. Если размер записи больше выделенного для В/В буфера, то нельзя выполнить левую табуляцию в позицию, принадлежащую предыдущему буферу. Если в результате применения дескриптора позиционирования выполнено перемещение правее последнего переданного символа и выполнен вывод нового значения, то пространство между концом предыдущего значения и началом нового значения будет заполнено пробелами. Дескриптор nX используется для перемещения позиции В/В на n символов вперед. Пример: real :: a = 1.23, b = 5.78, c write(*, 1) a, b ! a = 1.230 b = 5.780 1 format(T7, 'a = ', f6.3, TR7, 'b = ', f6.3) 315 О. В. Бартеньев. Современный ФОРТРАН read(*, '(20(f6.2, TL6))') a, b, c ! Введем: 4.67 write(*, '(4x, 3f6.2)') a, b, c ! 4.67 4.67 4.67 Управление выводом знака + в числовых полях выполняется при помощи дескрипторов SP, SS и S. Использование дескриптора SP обеспечивает вывод знака + в числовых полях, в которых выводятся положительные числа. Дескриптор SS подавляет вывод знака + (принимается по умолчанию). Дескриптор S восстанавливает действие дескриптора SS. Пример: real :: a = 1.23, b = 5.78 write(*, '(2f6.2)') a, b ! 1.23 5.78 write(*, '(sp, 2f6.2)') a, b !+1.23 +5.78 write(*, '(sp, f6.2, s, f6.2))') a, b !+1.23 5.78 Преобразование слеша. В текущей записи слеш (/) указывает на конец подлежащих передаче данных. При вводе слеш позиционирует файл за текущей записью. При выводе слеш обеспечивает простановку символов конца записи и позиционирует файл за этими символами. Перед слешем может быть задан коэффициент повторения. Пример: integer a(20) open(9, file = 'a.txt', blank = 'null') read(9, 1) a write(*, 1) a 1 format(7i3 / 5i3 / 8i3) Состав файла a.txt: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 -1 -2 -3 -4 -5 -6 -7 -8 -9 -10 При вводе по формату 1 из первой записи файла будут введены 7 чисел, из второй - 5 и из третьей - 8. Переход с одной записи на следующую обеспечивается преобразованием слеша. Результат вывода по формату 1: 1 2 3 4 5 6 7 11 12 13 14 15 -1 -2 -3 -4 -5 -6 -7 -8 Преобразование обратного слеша. По умолчанию при завершении передачи данных файл позиционируется вслед за обработанной записью, даже если переданы не все данные записи. Однако если последовательность ДП содержит обратный слеш (\), то продвижения файлового указателя при завершении исполнения оператора вывода не произойдет. Поэтому |