современный фортран , Бортеньев. О. В. Бартеньев Современный Фортран
Скачать 2.24 Mb.
|
Замечания: 1. Множество представимых в компьютере чисел с плавающей точкой конечно. Так, для типа REAL(4) их число примерно равно 2 31 2. FPS и CVF содержат программу BitViewer просмотра двоичного представления вещественных чисел одинарной и двойной точности. 6.11.2. Числовые справочные функции Эти функции выдают характеристики модели, в которой содержится параметр функции. Параметром функции может быть как скаляр, так и массив. Значение параметра может быть неопределенным. DIGITS(x) - возвращает число двоичных значащих цифр в модели представления x (т. е. Q или P). Параметр x может быть целого или вещественного типа. Результат имеет стандартный целый тип. Тип параметра x DIGITS(x) INTEGER(1) 7 INTEGER(2) 15 INTEGER(4) 31 REAL(4) 24 187 О. В. Бартеньев. Современный ФОРТРАН REAL(8) 53 EPSILON(x) - возвращает : P − 1 2 Тип параметра x EPSILON(x) REAL(8) 2.22044049250313E-016 REAL(4) 1.192093E-07 Замечание. Возвращаемое функцией и EPSILON число часто называют машинной точностью и обозначают ε м HUGE(x) - для целого или вещественного x возвращает наибольшее значение x. Тип и параметр типа результата такие же, как у x. Значение равно - для целого x и ( ) max 2 2 1 E P − − - для вещественного x. 1 2 − Q Тип параметра x HUGE(x ) INTEGER(1) 127 INTEGER(2) 32,767 INTEGER(4) 2,147,483,647 REAL(4) 3.402823E+38 REAL(8) 1.797693134862316E+308 MAXEXPONENT(x) - для вещественного x возвращает максимальное значение порядка, т. е. E max . Результат функции имеет стандартный целый тип. Тип параметра x MAXEXPONENT(x ) REAL(4) 128 REAL(8) 1024 MINEXPONENT(x) - для вещественного x возвращает минимальное значение порядка, т. е. E min . Результат функции имеет стандартный целый тип. Тип параметра x MINEXPONENT(x ) REAL(4) -125 REAL(8) -1021 PRECISION(x) - для вещественного или комплексного x возвращает число значащих цифр, следующих после десятичной точки, используемых для представления чисел с таким же параметром типа, как у x. Результат функции имеет стандартный целый тип. Тип параметра x PRECISION(x ) 188 6. Встроенные процедуры REAL(4) или COMPLEX(4) 6 REAL(8) или COMPLEX(8) 15 RADIX(x) - для целого или вещественного x возвращает стандартное целое, равное основанию системы счисления, используемой для представления чисел. Например: print *, radix(0.0) ! 2 RANGE(x) - для целого, вещественного или комплексного x возвращает эквивалентный десятичный степенной диапазон значений x, т. е. INT(LOG10(huge)) для целого и INT(MIN(LOG10(huge), -LOG10(tiny))) для вещественного или комплексного x, где huge и tiny - наибольшее и наименьшее числа в соответствующих разновидностях типа. Результат функции - стандартного целого типа. Тип параметра x RANGE(x ) INTEGER(1) 2 INTEGER(2) 4 INTEGER(4) 9 REAL(4) или COMPLEX(4) 37 REAL(8) или COMPLEX(8) 307 TINY(x) - для вещественного x возвращает наименьшее положительное значение x, т. е. . Тип и параметр типа результата такие же, как у x. min 2 E Тип параметра x TINY(x) REAL(4) 1.175494E-38 REAL(8) 2.225073858507201E-308 6.12. Элементные функции получения данных о компонентах представления вещественных чисел Функции такого рода возвращают значение, связанное с компонентами модельного представления фактического значения аргумента. EXPONENT(x) - возвращает степенную часть (т. е. порядок E) двоичного представления заданного вещественного x. Результат - стандартного целого типа. Результат равен нулю, если x = 0. Например: real(4) :: r1 = 1.0, r2 = 123456.7 real(8) :: r3 = 1.0d0, r4 = 123456789123456.7 189 О. В. Бартеньев. Современный ФОРТРАН write(*,*) exponent(r1) ! 1 write(*,*) exponent(r2) ! 17 write(*,*) exponent(r3) ! 1 write(*,*) exponent(r4) ! 47 FRACTION(x) - возвращает мантиссу - дробную часть двоичного представления x,т. е. . Тип x - вещественный. Тип и разновидность типа результата такие же, как у x. x E − 2 Например: print *, fraction(3.0) ! 0.75 print *, fraction(1024.0) ! 0.5 NEAREST(x, s) - возвращает вещественное значение с таким же параметром типа, как у x, равное ближайшему к x машинному числу, большему x, если s > 0, и меньшему x, если s < 0; s не может равняться нулю. Например: real(4) :: r1 = 3.0 real(8) :: r2 = 3.0_8 ! Используем для вывода шестнадцатеричную систему счисления write(*, '(1x,z18)') nearest (r1, 2.0) ! 40400001 write(*, '(1x,z18)') nearest (r1, -2.0) ! 403FFFFF write(*, '(1x,z18)') nearest (r2, 2.0_8) !4008000000000001 write(*, '(1x,z18)') nearest (r2, -2.0_8) !4007FFFFFFFFFFFF Замечание. Числа с плавающей точкой между нулем и HUGE(x) распределены неравномерно. В случае REAL(4) между каждыми соседними степенями двойки находится примерно 2 22 чисел с плавающей точкой. Так, примерно 2 22 чисел находится между 2 -125 и 2 -124 и столько же между 2 124 и 2 125 . Простое сопоставление говорит о том, что числа с плавающей точкой гуще расположены вблизи нуля. RRSPACING(x) - возвращает вещественное значение с таким же параметром типа, как у x, равное обратной величине относительного расстояния между числами в двоичном представлении x, в области, близкой к x, т. е. x E P − 2 x i x E i − 2 2 print *, rrspacing( 3.0_4) ! 1.258291e+07 print *, rrspacing(-3.0_4) ! 1.258291e+07 SCALE(x, i) - возвращает вещественное значение с таким же параметром типа, как у x, равное 2 , где i - целое число. print *, scale(5.2, 2) ! 20.800000 SET_EXPONENT(x, i) - возвращает вещественное значение с таким же параметром типа, как у x, равное , где i - целое число, а E = EXPO- NENT(x). 190 6. Встроенные процедуры SPACING(x) - возвращает вещественное значение с таким же параметром типа, как у x, равное абсолютному расстоянию между числами в двоичном представлении, в области, близкой к x, т. е. E P − 2 print *, spacing(3.0_4) ! 2.384186e-07 print *, spacing(-3.0_4) ! 2.384186e-07 6.13. Преобразования для параметра разновидности Следующие две функции возвращают минимальное значение параметра разновидности, удовлетворяющее заданным критериям. Аргументы и результаты функций - скаляры. Тип результата - стандартный целый. SELECT_INT_KIND(r) - возвращает значение параметра разновидности целого типа, в котором содержатся все целые числа интервала -10 r < n < 10 r При наличии более одной подходящей разновидности выбирается наименьшее значение параметра разновидности. Результат равен -1, если ни одна из разновидностей не содержит все числа интервала, задаваемого аргументом r. print *, selected_int_kind(8) ! 4 print *, selected_int_kind(3) ! 2 print *, selected_int_kind(10) ! -1 (нет подходящей разновидности) SELECTED_REAL_KIND([p] [, r]) - возвращает значение параметра разновидности вещественного типа, в котором содержатся все вещественные числа интервала -10 r < x < 10 r , десятичная точность которых не хуже p. Не допускается одновременное отсутствие двух аргументов. При наличии более одной подходящей разновидности выбирается разновидность с наименьшей десятичной точностью. Функция возвращает -1, если недоступна требуемая точность. Возвращает -2, если недоступен требуемый десятичный степенной диапазон. Возвращает -3, если недоступно и то и другое. Например: kp = 0 do while(selected_real_kind(p = kp) > 0) kp = kp + 1 end do kr = 300 do while(selected_real_kind(r = kr) > 0) kr = kr + 1 end do print *, selected_real_kind(p = kp), kp ! -1 16 print *, selected_real_kind(r = kr), kr ! -2 308 print *, selected_real_kind(kp, kr) ! -3 end 6.14. Процедуры для работы с битами Встроенные процедуры работают с битами, которые содержатся в машинном представлении целых чисел. В основе процедур лежит модель, 191 О. В. Бартеньев. Современный ФОРТРАН согласно которой целое число содержит s бит со значениями w k , k = 0, 1, ..., s - 1. Нумерация битов выполняется справа налево: самый правый бит имеет номер 0, а самый левый - s - 1. Значение w k k-го бита может равняться либо нулю, либо единице. 6.14.1. Справочная функция BIT_SIZE BIT_SIZE(i) - возвращает число бит, необходимых для представления целых чисел с такой же разновидностью типа, как у аргумента. Результат имеет тот же параметр типа, что и аргумент. Тип i BIT_SIZE(i ) INTEGER(1) 8 INTEGER(2) 16 INTEGER(4) 32 6.14.2. Элементные функции для работы с битами BTEST(i, pos) - возвращает стандартную логическую величину, равную .TRUE., если бит с номером pos целого аргумента i имеет значение 1, и .FALSE. - в противном случае. Аргумент pos должен быть целого типа и иметь значение в интервале 0 ≤ pos < BIT_SIZE(i). Пример: integer(1) :: iarr(2) = (/ 2#10101010, 2#11010101 /) logical result(2) result = btest(iarr, (/ 0, 0 /)) ! F T write(*, *) result write(*, *) btest(2#0001110001111000, 2) ! F write(*, *) btest(2#0001110001111000, 3) ! T IAND(i, j) - возвращает логическое И между соответствующими битами аргументов i и j: устанавливает в k-й разряд результата 1, если k-й разряд первого и второго параметров равен единице. В противном случае в k-й разряд результата устанавливается 0. Целочисленные аргументы i и j должны иметь одинаковые параметры типа. Тот же параметр типа будет иметь и результат. IBCHNG(i, pos) - возвращает целый результат с таким же параметром типа, как у i, и значением, совпадающим с i, за исключением бита с номером pos, значение которого заменяется на противоположное. Аргумент pos должен быть целым и иметь значение в интервале 0 ≤ pos < BIT_SIZE(i). IBCLR(i, pos) - возвращает целый результат с таким же параметром типа, как у i, и значением, совпадающим с i, за исключением бита с номером pos, который обнуляется. Аргумент pos должен быть целым и иметь значение в интервале 0 ≤ pos < BIT_SIZE(i). 192 6. Встроенные процедуры IBITS(i, pos, len) - возвращает целый результат с таким же параметром типа, как у i, и значением, равным len битам аргумента i, начиная с бита с номером pos; после смещения этой цепочки из len бит вправо и обнуления всех освободившихся битов. Аргументы pos и len должны быть целыми и иметь неотрицательные значения, такие, что pos + len ≤ BIT_SIZE(i). Например: k = ibits(2#1010, 1, 3) ! Возвращает 2#101 = 5 print '(b8)', k ! 101 IBSET(i, pos) - возвращает целый результат с таким же параметром типа, как у i, и значением, совпадающим с i, за исключением бита с номером pos, в который устанавливается единица. Аргумент pos должен быть целым и иметь значение в интервале 0 ≤ pos < BIT_SIZE(i). IEOR(i, j) - возвращает логическое исключающее ИЛИ между соответствующими битами аргументов i и j: устанавливает в k-й разряд результата 0, если k-й разряд первого и второго параметров равен или единице, или нулю. В противном случае в k-й разряд результата устанавливается единица. Целочисленные аргументы i и j должны иметь одинаковые параметры типа. Тот же параметр типа будет иметь и результат. IOR(i, j) - возвращает логическое ИЛИ между соответствующими битами аргументов i и j: устанавливает в k-й разряд результата единицу, если k-й разряд хотя бы одного параметра равен единице. В противном случае в k-й разряд результата устанавливается 0. Целочисленные аргументы i и j должны иметь одинаковые параметры типа. Тот же параметр типа будет иметь и результат. Пример: integer(2) :: k = 198 ! 198 ( = 2#11000110 ) integer(2) :: mask = 129 ! 129 ( = 2#10000001 ) write(*, *) iand(k, mask) ! 128 ( = 2#10000000 ) write(*, *) ieor(k, mask) ! 71 ( = 2#01000111 ) write(*, *) ior(k, mask) ! 199 ( = 2#11000111 ) ISHA(i, shift) - (арифметический сдвиг) возвращает целый результат с таким же параметром типа, как у i, и значением, получаемым в результате сдвига битов параметра i на shift позиций влево (или на -shift позиций вправо, если значение shift отрицательно). Освобождающиеся при сдвиге влево биты обнуляются, а при сдвиге вправо заполняются значением знакового бита. Аргумент shift должен быть целым и удовлетворять неравенству |shift| ≤ BIT_SIZE(i). ISHC(i, shift) - (циклический сдвиг) возвращает целый результат с таким же параметром типа, как у i, и значением, получаемым в результате циклического сдвига всех битов параметра i на shift позиций влево (или на - shift позиций вправо, если значение shift отрицательно). Циклический сдвиг выполняется без потерь битов: вытесняемые с одного конца биты 193 О. В. Бартеньев. Современный ФОРТРАН появляются в том же порядке на другом. Аргумент shift должен быть целым, причем |shift| ≤ BIT_SIZE(i). ISHFT(i, shift) - (логический сдвиг) возвращает целый результат с таким же параметром типа, как у i, и значением, получаемым в результате сдвига битов параметра i на shift позиций влево (или на -shift позиций вправо, если значение shift отрицательно). Освобождающиеся биты как при левом, так и при правом сдвиге обнуляются. В отличие от арифметического сдвига, сдвигается и знаковый разряд. Аргумент shift должен быть целым и удовлетворять неравенству |shift| ≤ BIT_SIZE(i). ISHTC(i, shift [, size]) - возвращает целый результат с таким же параметром типа, как у i, и значением, получаемым в результате циклического сдвига size младших (самых правых) битов параметра i (или всех битов, если параметр size опущен) на shift позиций влево (или на -shift позиций вправо, если значение shift отрицательно). Аргументы shift и size должны быть целыми, причем 0 < size ≤ BIT_SIZE(i); |shift| ≤ size или |shift| ≤ BIT_SIZE(i), если опущен параметр size. ISHL(i, shift) - выполняет те же действия, что и функция ISHFT. Пример: integer(1) :: k = -64 ! -64 ( = 2#11000000 ) integer(1) :: i = 10 ! 10 ( = 2#00001010 ) integer(2) :: j = 10 ! 10 ( = 2#0000000000001010 ) ! Функция ISHA (правый сдвиг) print '(1x, b8.8)', isha(k, -3) ! 11111000 ( = -8 ) ! Функция ISHL (правый сдвиг) print '(1x, b8.8)', ishl(k, -3) ! 00011000 ( = 24 ) ! Функция ISHC (левый сдвиг) print '(1x, b8.8)', ishc(i, 5) ! 01000001 ( = 65 ) ! Функция ISHFT (тот же результат выдадут функции ISHA и ISHL) print '(1x, b8.8)', ishft(i, 5) ! 01000000 ( = 64 ) ! Функция ISHFTC print '(1x, b8.8)', ishftc(i, 2, 3) ! 00001001 ( = 9 ) print '(1x, b8.8)', ishftc(i, -2, 3) ! 00001100 ( = 12 ) print '(1x, b16.16)', ishftc(j, 2, 3) ! 0000000000001001 ( = 9 ) NOT(i) - (логическое дополнение) возвращает целый результат с таким же параметром типа, как у i. Бит результата равен единице, если соответствующий бит параметра i равен нулю, и, наоборот, бит результата равен нулю, если соответствующий бит параметра i равен единице. Например, NOT(2#1001) возвращает 2#0110. 6.14.3. Элементная подпрограмма MVBITS CALL MVBITS(from, frompos, len, to, topos) - копирует из from последовательность из len бит, начиная с бита номер frompos, в to, начиная с бита номер topos. Остальные биты в to не меняются. Отсчет позиций 194 6. Встроенные процедуры выполняется начиная с самого правого бита, номер которого равен нулю. Параметры from, frompos, len и topos имеют целый тип и вид связи IN: to - параметр целого типа с видом связи INOUT. Параметры должны удовлетворять условиям: len ≥ 0, frompos + len ≤ BIT_SIZE(from), frompos ≥ 0, topos ≥ 0, topos + len ≤ BIT_SIZE(to). Параметры from и to должны иметь одну разновидность типа. В качестве from и to можно использовать одну и ту же переменную. Пример: integer(1) :: iso = 13 ! 2#00001101 integer(1) :: tar = 6 ! 2#00000110 call mvbits(iso, 2, 2, tar, 0) ! Возвращает tar = 00000111 6.14.4. Пример использования битовых функций Достаточно часто поразрядные операции находят применение в программах машинной графики. Рассмотрим в качестве примера применяемый в машинной графике для решения задачи отсечения алгоритм Сазерленда - Кохена. Задача отсечения заключается в удалении элементов изображения, лежащих вне заданной границы (рис. 6.2). Возьмем задачу, в которой границей области является прямоугольник, который далее мы будем называть окном вывода. Задача отсечения многократно решается при работе с изображением для большого числа отрезков, поэтому важно, чтобы алгоритм ее решения обладал высоким быстродействием. В машинной графике экран монитора отображается на растровую плоскость, размеры которой зависят от возможностей видеоадаптера и монитора. Координаты на растровой плоскости целочисленные. Учитывая обеспечиваемое видеоадаптерами разрешение, например 800 * 600 или 1024 * 768 пикселей, для координат используется тип INTEGER(2). В алгоритме Сазерленда - Кохена взаимное расположение отрезка и окна вывода определяется так. Окно вывода разбивает своими сторонами и их продолжениями растровую плоскость на 9 областей. Установим для каждой области 4-битовый код (рис. 6.2), в котором: • единица в бите 0 означает, что точка лежит ниже окна вывода; • единица в бите 1 означает, что точка лежит правее окна вывода; • единица в бите 2 означает, что точка лежит выше окна вывода; • единица в бите 3 означает, что точка лежит левее окна вывода. Пусть 1 и 2 - номера вершин отрезка; c1 и c2 - коды областей расположения соответственно первой и второй вершины. XL, XR, YB, YT - координаты границ окна вывода. Очевидно, что • отрезок расположен внутри окна, если IOR(c1, c2) возвращает 0; • отрезок не пересекает окно, если IAND(c1, c2) > 0; • отрезок может пересекать окно, если IAND(c1, c2) возвращает 0 и IOR(c1, c2) > 0. |