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

5. Выражения, операции и присваивание

В настоящей главе обобщаются сведения о выражениях и операциях. Операции применяются для создания выражений, которые затем используются в операторах Фортрана.

Операции Фортрана разделяются на встроенные и задаваемые программистом (перегружаемые).

Встроенные операции:

арифметические;

символьная операция конкатенации (объединение символьных строк);

операции отношения;

логические.

Символьные выражения и операция конкатенации в этой главе не рассматриваются, поскольку подробно изложены в разд. 3.8.5.

Часть арифметических действий реализована в Фортране в виде встроенных функций, например вычисление остатка от деления, усечение и округление, побитовые операции и др. Рассмотрение встроенных функций выполнено в следующей главе.

Выражения подразделяются на скалярные и выражения-массивы. Результатом выражения-массива является массив или его сечение. По крайней мере одним из операндов выражения-массива должны быть массив или сечение массива, например:

real :: a(5) = (/ (i, i = 1, 5) /)

 

a(3:5) = a(1:3) * 2

! Возвращает (1.0 2.0 2.0 4.0 6.0)

5.1. Арифметические выражения

Результатом арифметического выражения может быть величина целого, или вещественного, или комплексного типа или массив (сечение) одного из этих типов. Операндами арифметического выражения могут быть:

арифметические константы;

скалярные числовые переменные;

числовые массивы и их сечения;

вызовы функций целого, вещественного и комплексного типа.

5.1.1. Выполнение арифметических операций

Арифметические операции различаются приоритетом:

** возведение в степень (операция с наивысшим приоритетом); *, / умножение, деление; одноместные (унарные) + и -; +, - сложение, вычитание.

158

5. Выражения, операции и присваивание

Замечание. В Фортране в отличие от СИ унарным операциям не может предшествовать знак другой операции, например:

k = 12

/ -a

! Ошибка

k = 12

/ ( -a )

! Правильно

Операции Фортрана, кроме возведения в степень, выполняются слева направо в соответствии с приоритетом. Операции возведения в степень выполняются справа налево. Так, выражение -a + b + c будет выполнено в следующем порядке: (((-a) + b) + c). А выражение a**b**c вычисляется так: (a**(b**c)). Заключенные в круглые скобки подвыражения вычисляются в первую очередь.

Пример:

k = 2 * 2 ** 2 / 2 / 2

! 2

! Проиллюстрируем последовательность вычислений, расставив скобки:

k = ((2 * (2 ** 2)) / 2) / 2

! 2

! Проиллюстрируем влияние скобок на результат выражения

k = 2

** 8 / 2 + 2

! 130

k = 2

** (8 / 2 + 2)

! 64

k = 2

** (8 / (2 + 2))

! 4

В арифметических выражениях запрещается:

делить на нуль;

возводить равный нулю операнд в отрицательную или нулевую степень;

возводить отрицательный операнд в нецелочисленную степень.

Пример:

a = (-2)**2.2

! Ошибка - нарушение последнего ограничения

5.1.2. Целочисленное деление

Рассмотрим простую программу:

real(4) dp, dn dp = 3 / 2 dn = -3 / 2

print *, dp, dn ! 1.0 -1.0 end

Программисты, впервые наблюдающие целочисленное деление, будут удивлены, увидев в качестве результата 1.0 и -1.0 вместо ожидаемых ими 1.5 и -1.5. Однако результат имеет простое объяснение: 3, -3 и 2 - целые числа и результатом деления будут также целые числа - целая часть числа 1.5 и целая часть числа -1.5, т. е. 1 и -1. Затем, поскольку переменные dp и dn имеют тип REAL(4), целые числа 1 и -1 будут преобразованы в стандартный вещественный тип.

159

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

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

dp = 2.0/3.0 или dp = 2/3.0, или dp = 2.0/3

Можно также воспользоваться функциями явного преобразования целого типа данных в вещественный (разд. 6.5) и записать, например,

d = float(2)/float(3) или d = real(2)/real(3)

Еще несколько примеров целочисленного деления: 2 ** (-2) возвращает 0 (целочисленное деление);

2.0 ** (-2) возвращает 0.25 (нет целочисленного деления); -7/3 возвращает -2; 19/10 возвращает 1; 1/4 + 1/4 возвращает 0.

5.1.3. Ранг и типы арифметических операндов

В Фортране допускается использовать в арифметическом выражении операнды разных типов и разновидностей типов. В таком случае результат каждой операции выражения определяется по следующим правилам:

если операнды арифметической операции имеют один и тот же тип, то результат операции имеет тот же тип. Это правило хорошо иллюстрируется целочисленным делением;

если операнды операции имеют различный тип, то результат операции имеет тип операнда наивысшего ранга.

Ранг типов арифметических операндов (дан в порядке убывания): COMPLEX (8) или DOUBLE COMPLEX - наивысший ранг; COMPLEX (4);

REAL(8) или DOUBLE PRECISION; REAL(4) или REAL;

INTEGER(4) или INTEGER; INTEGER(2);

INTEGER(1) или BYTE - низший ранг.

Пример:

integer(2) :: a = 1, b = 2

 

real(4) :: c = 2.5

 

real(8) d1, d2

 

d1

= a / b * c

! 0.0_8

d2

= a / (b * c)

! 0.2_8

При вычислении d2 первоначально выполняется операция умножения, но прежде число 2 типа INTEGER(2) переводится в тип REAL(4). Далее

160

5. Выражения, операции и присваивание

выполняется операция деления, и вновь ее предваряет преобразование типов: число 1 типа INTEGER(2) переводится в тип REAL(4). Выражение возвращает 0.2 типа REAL(4), которое, однако, в результате присваивания преобразовывается в тип REAL(8). При этом типы операндов выражения - переменных a и b, разумеется, сохраняются.

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

integer :: a = 8, b = 3

 

real c

 

c = 2.0**(a / b)

! 4.0

c = 2.0**(float(a) / float(b))

! 6.349604

Встроенные математические функции, обладающие специфическими именами, требуют точного задания типа аргумента, например:

real(4) :: a = 4

 

real(8) :: b = 4, x

 

x = dsqrt(a)

! Ошибка: тип параметра должен быть REAL(8)

x = dsqrt(b)

! Верно

Перевод числа к большей разновидности типа, например от REAL(4) к REAL(8), может привести к искажению точности, например:

real(4) :: a = 1.11

 

 

real(8) :: c

 

 

c = a

 

 

print *, a

!

1.110000

print *, c

!

1.110000014305115

В то же время если сразу начать работу с типом REAL(8), то точность сохраняется, например:

real(8) :: c

 

 

c = 1.11_8

! или c = 1.11d0

print *, c

!

1.110000000000000

Искажение значения может произойти и при переходе к низшей разновидности типа, например:

integer(2) :: k2 = 325

! -128 <= k1 <= 127

integer(1) :: k1

k1 = k2

 

 

print *, k2

!

325

print *, k1

!

69

5.1.4. Ошибки округления

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

161