ЛАБОРАТОРНЫЙ ПРАКТИКУМ: «ПРОГРАММИРОВАНИЕ НА ФОРТРАНЕ»
СТРУКТУРА ПРАКТИКУМА
ВВЕДЕНИЕ
ВАЖНАЯ ИНФОРМАЦИЯ
1. ПРАВИЛА ЗАПИСИ ПРОГРАММЫ
1. Набор символов Фортрана
2. Форматы записи программы
3. Фиксированный формат
4. Свободный формат
2. ТРАНСЛЯЦИЯ ПРОГРАММЫ
1. Программа в одном исходном файле
2. Трансляция исходного файла
3. Трансляция нескольких исходных файлов
4. Трансляция модулей
3. КОНЦЕПЦИЯ ДАННЫХ ЯЗЫКА ФОРТРАН
1. Имена (идентификаторы)
2. Понятие типа
3. Буквальные константы
4. Разновидности типов и диапазоны значений
5. Скалярные переменные и константы
6. Массивы
7. Производные типы данных
4. ВЫРАЖЕНИЯ И ПРЕОБРАЗОВАНИЕ ТИПОВ
1. Скалярное присваивание
2. Арифметика Фортрана
3. Логические выражения
4. Работа с текстовыми строками
5. Операции с массивами
5. УПРАВЛЯЮЩИЕ ОПЕРАТОРЫ
1. Условный оператор и конструкция IF
2. Оператор варианта – конструкция CASE
3. Циклы – разновидности конструкции DO
4. Оператор GO TO
6. ВВОД/ВЫВОД ДАННЫХ
1. Простейшие операции ввода/вывода
2. Форматный ввод/вывод данных
3. Ввод/вывод массивов в неявных циклах
4. Файловый ввод/вывод
7. ПРОГРАММНЫЕ КОМПОНЕНТЫ И ЭЛЕМЕНТЫ ООП
1. Структура программных компонентов
2. Внешние подпрограммы
3. Внутренние подпрограммы
4. Модули как библиотеки производных типов
5. Встроенные функции Фортрана
ЗАДАЧИ ДЛЯ ПРОГРАММИРОВАНИЯ
3.4. Разновидности типов и диапазоны значений
Очевидно, что для объекта данных любого типа выделяется некоторая память (в машинных словах или байтах). Иногда эта память может оказаться избыточной (если например, для целых чисел в диапазоне ±127 отводится по два или четыре байта, тогда как вполне достаточно одного байта). Это может иметь серьезное значение при обработке больших массивов данных, характерных для математических моделей сложных физических процессов и технических систем.
Идея разновидности типа заключается в том, чтобы, обеспечить требуемый диапазон значений данных, с максимальной экономией памяти, независимо от применяемого компьютера и операционной системы. Т.е. нужно определить минимальное количество байтов, необходимых для хранения данных – эта величина в Фортране 90/95 имеет название параметра разновидности типа, и имеет обозначение KIND.
Значение параметра разновидности KIND можно вычислить заранее (до программирования) или использовать специальные функции Фортрана. Предположим, требуется обеспечить работу с целыми числами в диапазоне от – 9999 до 9999 (т.е. работу с целыми величинами в пределах 4-х значащих цифр). В этом случае значение параметра разновидности можно получить с помощью специальной встроенной функции SELECTED_INT_KIND – аргументом функции будет количество значащих цифр (Пример 3.1).
Пример 3.1. Определение параметра KIND через буквальную константу.
program INT4KIND print*, SELECTED_INT_KIND(4) end
В Примере 3.2. значение функции SELECTED_INT_KIND(4) присваивается константе с именем K4 (может быть любое другое имя), затем объявляются целые переменные X, Y и Z с параметром разновидности KIND=K4. Переменные инициализируются целыми буквальными константами соответствующей разновидности целого типа (см. также п. 3.5).
Пример 3.2. Определение параметра KIND через SELECTED_INT_KIND.
program INT4KIND integer(kind=1), parameter :: K4=SELECTED_INT_KIND(4) integer(kind=K4) :: X=1235_K4, Y=4678_K4, Z=90_K4 print*, K4, X, Y, Z end
Для определения параметра разновидности вещественных значений используется функция SELECTED_REAL_KIND (Пример 3.3). Если требуется точность не менее девяти значащих цифр (первый аргумент) и степенной диапазон в пределах от 1.E–99 до 1.E+99 (второй аргумент) то значение KIND можно вычислить указав соответствующие аргументы: SELECTED_REAL_KIND(9, 99).
Пример 3.3. Определение параметра KIND через SELECTED_REAL_KIND.
program REALONG integer(kind=1), parameter :: LONG=SELECTED_REAL_KIND(9,99) real(kind=LONG) :: X=1.234567895E+98_LONG print*, LONG, X end
С помощью встроенных функций Фортрана можно решить обратную задачу – определить диапазон значений для заданной разновидности типа KIND.
Для определения модуля максимального значения данной разновидности целого типа, например KIND=8, можно воспользоваться встроенной функцией HUGE (Пример 3.4).
Пример 3.4. Максимальное значение для 8-байтовых INTEGER
program MAXINT8 integer (kind=8) X print *, huge(X) end
Для определения модуля максимального значения данной разновидности вещественного типа, например, KIND=16, также можно воспользоваться встроенной функцией HUGE, а для определения границ машинного нуля – функцией TINY (Пример 3.5).
Пример 3.5. Диапазон значений и машинный ноль 16-байтовых REAL
program MAXMINREAL16 real (kind=16) X print *, huge(X), tiny(X) end
Компилятор Gfortran предусматривает для данных встроенных типов следующие значения параметра разновидности типа:
Для целых чисел (INTEGER):
KIND=1 (однобайтные целые) в пределах: ±127
KIND=2 (двухбайтные целые) в пределах: ±32767
KIND=4 (двухбайтные целые) в пределах: ±2147483647
KIND=8 (восьмибайтные целые): ±9223372036854775807_8
По умолчанию (если параметр разновидности не указан), для целых чисел разновидность KIND=4 считается стандартной.
Для данных вещественного типа REAL:
KIND=4 (четырехбайтные REAL) в пределах: ± 3.40282347E+38, где границы машинного нуля: ±1.17549435E–38
KIND=8 в пределах: ±1.79769313486231571E+308_8 , где границы машинного нуля: ±2.22507385850720138E–308_8
KIND=16 имеют значения в пределах:
±1.18973149535723176508575932662800702E+4932_16 , при этом границы машинного нуля:
± 3.36210314311209350626267781732175260E-4932_16
Стандартной разновидностью вещественного типа, по умолчанию, считается KIND=4.
Константа, для которой KIND=4 или параметр разновидности не задан, имеет точность до 7 значащих цифр.
Для комплексных буквальных констант(COMPLEX):
Разновидность типа определяется в соответствии со следующими правилами:
Если вещественная и мнимая часть комплексного числа заданы целыми числами, то разновидность комплексной константы совпадает со стандартной разновидностью вещественных чисел. Для компилятора Gfortran это означает KIND=4.
Если имеет место комбинация целого и вещественного числа, то разновидность комплексной константы совпадает с разновидностью вещественного числа.
При наличии двух вещественных чисел с несовпадающими разновидностями максимальная из них будет являться разновидностью комплексной константы. Если разновидность у двух вещественных чисел одна и та же, то такую же разновидность будет иметь комплексная константа.
Компилятор Gfortran работает со следующими разновидностями логических буквальных констант (LOGICAL):
KIND=1 – байт, содержащий либо 0 (.FALSE.), либо 1 (.TRUE.).
KIND=2 – двухбайтовый объект логического типа. Старший байт соответствует KIND=1, второй содержит значение NULL.
KIND=4 – четырехбайтовый объект логического типа. Старший (первый) байт в точности аналогичен KIND=1, остальные содержат значение NULL.
Для символьных (текстовых) данных (CHARACTER), параметр разновидности KIND типа применяется для указания кодовой таблицы символов, например: ASCII, UTF, Windows-1251и т.д. Оптимальная кодовая таблица всегда задана операционной системой, поэтому параметр KIND лучше не использовать без крайней необходимости. Более детально работа с текстовыми строками рассмотрена в п.4.4.
Правильное (или неправильное) представление буквальных констант может серьезно и даже критично отражаться на точности вычислений. Если, например, для каких-то вычислений потребовалось число π с точностью до 15-ти значащих цифр, то недостаточно объявить соответствующую вещественную переменную или константу как real (KIND=8). Не менее важно правильно инициализировать такую переменную или константу (т.е. присвоить ей первоначальное значение).
В Примере 3.6. две такие константы (PI_1 и PI_2) инициализируются двумя почти одинаковыми вещественными константами. Однако, запустив и выполнив эту программу можно увидеть ощутимую разницу: для константы PI_1 обеспечена точность только до 7 значащих цифр, а для переменной PI_2 – 15 значащих цифр, как и требовалось. Дело в том, что буквальная константа не содержащая явного описания разновидности типа (как PI_1) считается буквальной константой стандартной разновидности (т.е. KIND=4) и может обеспечивать соответствующую точность (и не более того) в независимости от того сколько значащих цифр указано в ее записи. Соответственно константа 3.1415926535897931 может обеспечить точность только 7 значащих цифр, тогда как константа с явным указанием параметра разновидности 3.1415926535897931_8 (постфикс «_8»явно определяет параметр разновидности) обеспечивает требуемую точность (Пример 3.6).
Пример 3.6. Точность представления 8-байтовых целых констант
program PRECINT8 real (kind=8), parameter :: PI_1=3.1415926535897931, & PI_2=3.1415926535897931_8 print*, PI_1 print*, PI_2 end