Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
современный фортран , Бортеньев.pdf
Скачиваний:
242
Добавлен:
26.03.2015
Размер:
2.34 Mб
Скачать

О. В. Бартеньев. Современный ФОРТРАН

subroutine swap(a, b) integer(2) a, b, hold

hold = a; a = b; b = hold end subroutine swap

! Вычисление кода области расположения вершины с координатами x, y function code(x, y, XL, XR, YB, YT) result (vcode)

integer(2) x, y, XL, XR, YB, YT, vcode vcode = 0

if(x < XL) vcode = ior(vcode, 2#1000) if(y < YB) vcode = ior(vcode, 2#0001) if(x > XR) vcode = ior(vcode, 2#0010) if(y > YT) vcode = ior(vcode, 2#0100) end function code

6.15. Символьные функции

Встроенные символьные функции ADJUSTL, ADJUSTR, LGE, LGT, LLE, LLT, INDEX, LEN_TRIM, REPEAT, SCAN, TRIM, VERIFY позволяют сравнивать символьные выражения, вычислять их длину, осуществлять поиск в строках других подстрок и выполнять преобразования строк. Функции рассмотрены в разд. 3.8.8.

6.16. Процедуры для работы с памятью

LOC(gen) - встроенная функция; возвращает машинный адрес аргумента gen или адрес временного результата для аргумента gen. Результат имеет тип INTEGER(4).

Если параметр gen является выражением, вызовом функции или константой, то создается временная переменная, содержащая результат выражения, вызов функции или константу, и функция LOC возвращает адрес этой временной переменной. Во всех других случаях функция возвращает машинный адрес фактического параметра.

MALLOC(i) - встроенная функция; выделяет область памяти размером в i байт. Функция возвращает начальный адрес выделенной памяти. Тип аргумента и результата функции - INTEGER(4).

CALL FREE(i) - встроенная подпрограмма; освобождает выделенную функцией MALLOC область памяти; i - начальный адрес выделенной функцией MALLOC памяти. Тип параметра i - INTEGER(4).

Предупреждение. Если освобождаемая память не была ранее выделена функцией MALLOC или память освобождается более одного раза, то результат непредсказуем и выполнение подпрограммы FREE может серьезно повредить занимаемую программой память.

198

 

6. Встроенные процедуры

Пример:

 

integer(4) addr, size

 

size = 1024

! Размер в байтах

addr = malloc(size)

! Выделяем память размером size

...

 

call free(addr)

! и освобождаем ее

end

 

6.17. Проверка состояния "конец файла"

Встроенная функция EOF(устройство) возвращает .TRUE., если файл позиционирован на запись "конец файла" или вслед за этой записью, и .FALSE. - в противном случае. (Рассмотрена в разд. 11.16.)

6.18. Неэлементные подпрограммы даты и времени

CALL DATE_AND_TIME([date] [, time] [, zone] [, values]) - возвращает дату и время, которые показывают встроенные системные часы. Все параметры процедуры имеют вид связи OUT.

date - текстовая скалярная переменная длиной не менее восьми символов, содержащая в восьми первых символах дату в виде CCYYMMDD, где CC соответствует веку, YY - году, MM - месяцу, DD - дню.

time - текстовая скалярная переменная длиной не менее 10 символов, содержащая в 10 первых символах время в виде HHMMSS.SSS, где HH соответствует часу, ММ - минутам, SS - секундам, SSS - миллисекундам. zone - текстовая скалярная переменная длиной не менее пяти символов, содержащая в пяти первых символах разницу между местным временем

иуниверсальным согласованным временем (средним временем по Гринвичу)

ввиде SHHMM, где S - знак (+ или -), HH - часы, MM - минуты.

values - одномерный стандартный целый массив размером не менее восьми, содержащий последовательность значений: год, месяц, день, разница во времени (в минутах) по отношению ко времени по Гринвичу, час дня, минуты, секунды, миллисекунды. Если какое-либо значение недоступно, то соответствующий элемент массива равен HUGE(0).

character(10) dat, tim, zon

call date_and_time(date = dat, time = tim, zone = zon) print *, dat, tim, ' ', zon

CALL SYSTEM_CLOCK([count] [, count_rate] [, count_max]) -

возвращает текущее значение системного таймера и его характеристики. Все параметры имеют стандартный целый тип. Вид связи параметров - OUT.

count - текущее значение системного таймера или HUGE(0) при его отсутствии. Значение count увеличивается на единицу при каждом отсчете

199

О. В. Бартеньев. Современный ФОРТРАН

таймера до тех пор, пока не достигнет значения count_max. После чего, начиная с нуля, выполняется новый цикл отсчета времени.

count_rate - число отсчетов таймера в секунду или 0, если таймер отсутствует.

count_max - максимальное значение, которое может принимать count или 0, если таймер отсутствует.

integer cr, cm

call system_clock(count_rate = cr, count_max = cm) write(*,*) cr, cm ! 1 86399

Подпрограмму DATE_AND_TIME можно приспособить для измерения времени вычислений, создав функцию timer:

function timer( )

! Возвращает процессорное время

real(8) :: timer

! в миллисекундах

 

integer(4) :: ival(8)

 

 

call date_and_time(values = ival)

 

timer = dble(ival(8)) * 0.001_8 +

&

dble(ival(7)) + dble(ival(6)) * 60.0_8 +

&

dble(ival(5)) * 3600.0_8

 

end function timer

 

 

Пример. Замеряется время вычислений при правильной и неоптимальной организации вложенных циклов.

program toappr

integer(4), parameter :: n = 1000 real(4), dimension(n, n) :: array1, array2

real(8) :: start_time1, finish_time1

! Время начала и завершения вычислений

real(8) :: start_time2, finish_time2

! соответственно при правильной и

 

! неоптимальной организации вложенных циклов

real(8) :: timer

! Функция, возвращающая процессорное время

 

! в миллисекундах; имеет тип REAL(8)

array1 = 1.1; array2 = 1.5

! Инициализация массивов

!Правильная организация вложенного цикла обеспечивает естественный доступ

!к элементам массива по столбцам

start_time1 = timer( )

! Начало вычислений

do j = 1, n

! Правильно: сначала задается столбец,

do i = 1, n

! а затем меняется индекс строки

array1(i, j) = array1(i, j) + array2(i, j) * 3.3

end do

 

end do

 

finish_time1 = timer( )

! Конец вычислений

array1 = 1.1; array2 = 1.5

! Повторная инициализация массивов

!Неоптимальная организация вложенного цикла - неестественный доступ

!к элементам массива по строкам

start_time2 = timer( )

! Начало вычислений

do i = 1, n

! Так программировать не надо. Обеспечьте

do j = 1, n

! доступ к элементам массива по столбцам

200

6. Встроенные процедуры

array1(i, j) = array1(i, j) + array2(i, j) * 3.3 end do

end do

finish_time2 = timer( ) ! Конец вычислений

print *, (finish_time1 - start_time1) / (finish_time2 - start_time2) ! Результат: 0.629629629613660

end program toappr

6.19. Случайные числа

Генерация случайных чисел выполняется подпрограммой RANDOM_NUMBER от значений, содержащихся в затравочном массиве. Размер и значения этого массива возвращаются подпрограммой RANDOM_SEED. Она же позволяет и изменить затравку.

CALL RANDOM_NUMBER(harvest) - возвращает псевдослучайное число harvest или массив harvest таких чисел из равномерно распределенного интервала: 0 x < 1. Тип harvest - стандартный вещественный. Вид связи параметра harvest - OUT.

Стартовая (затравочная) точка для генератора случайных чисел устанавливается и может быть запрошена RANDOM_SEED. Если RANDOM_SEED не использована, то значение затравки зависит от процессора.

real x, hav(3)

 

call random_seed( )

 

call random_number(x)

 

call random_number(hav)

 

print *, hav

! 5.252978E-01 6.502543E-01 4.247389E-01

CALL RANDOM_SEED([size] [, put] [, get]) - изменяет стартовую точку

(затравку) генератора псевдослучайных чисел, используемого подпрограммой RANDOM_NUMBER.

size - стандартное целое число, имеющее вид связи OUT, равное размеру n создаваемого процессором затравочного массива.

put - стандартный целый массив с видом связи IN, используемый процессором для изменения затравки.

get - стандартный целый массив с видом связи OUT, в который заносятся текущие значения затравки.

При вызове RANDOM_SEED должно быть задано не более одного параметра. Размеры put и get должны быть больше, чем размер массива, который используется процессором для хранения затравочных чисел. Этот размер можно определить, вызвав RANDOM_SEED с параметром size. В настоящей реализации size = 1.

Если при вызове RANDOM_SEED не задано ни одного параметра, то процессор устанавливает стартовую точку генератора случайных чисел в зависимости от системного времени.

201