Spec-Zone.ru › Ada 2005
Руководство по Ada 2005

4.5.5 Операторы умножения

Статическая семантика

Операторы умножения * (умножение), / (деление), mod (модуль) и rem (остаток) определены для каждого конкретного целого типа T:
function "*" (Left, Right : T) return T
function "/" (Left, Right : T) return T
function "mod"(Left, Right : T) return T
function "rem"(Left, Right : T) return T
Умножение целых со знаком имеет общепринятое значение.
Целочисленное деление и остаток со знаком определяются соотношением:
A = (A/B)*B + (A rem B)
где (A rem B) имеет знак A и абсолютное значение меньше абсолютного значения B. Целочисленное деление со знаком удовлетворяет тождеству:
(-A)/B = -(A/B) = A/(-B)
Оператор модуля целых со знаком определяется таким образом, что результат A mod B имеет знак B и абсолютное значение меньше абсолютного значения B; кроме того, для некоторого целого значения N со знаком этот результат удовлетворяет соотношению:
A = B*N + (A mod B)
Операторы умножения для типов по модулю определяются через соответствующие операторы целых со знаком, за которыми следует приведение по модулю, если результат находится вне базового диапазона типа (что возможно только для оператора "*").
Операторы умножения и деления определены для каждого конкретного типа с плавающей точкой T:
function "*"(Left, Right : T) return T
function "/"(Left, Right : T) return T
Следующие операторы умножения и деления с операндом предопределенного типа Integer определены для каждого конкретного типа с фиксированной точкой T:
function "*"(Left : T; Right : Integer) return T
function "*"(Left : Integer; Right : T) return T
function "/"(Left : T; Right : Integer) return T
Все вышеперечисленные операторы умножения могут использоваться с операндом соответствующего универсального числового типа. Следующие дополнительные операторы умножения для root_real определены и могут использоваться, когда оба операнда являются соответствующим универсальным или корневым числовым типом, а результат разрешен быть типа root_real, как в объявлении_числа:
function "*"(Left, Right : root_real) return root_real
function "/"(Left, Right : root_real) return root_real
function "*"(Left : root_real; Right : root_integer) return root_real
function "*"(Left : root_integer; Right : root_real) return root_real
function "/"(Left : root_real; Right : root_integer) return root_real
Умножение и деление между любыми двумя типами с фиксированной точкой предоставляются следующими двумя предопределенными операторами:
function "*"(Left, Right : universal_fixed) return universal_fixed
function "/"(Left, Right : universal_fixed) return universal_fixed

Правила разрешения имен

Вышеуказанные два оператора умножения fixed-fixed не должны использоваться в контексте, где ожидаемый тип результата сам по себе является universal_fixed — контекст должен определить какой-либо другой числовой тип, в который будет преобразован результат, явно или неявно. Если предопределенный универсальный оператор не определен с помощью расширенного имени с префиксом, обозначающим пакет Standard, то явное преобразование результата необходимо при использовании указанного оператора умножения fixed-fixed, если хотя бы один операнд имеет тип с пользовательским определенным оператором умножения, таким что:
  • он объявлен непосредственно в том же списке объявлений, что и тип; и
  • оба его формальных параметра являются типами с фиксированной точкой.
Соответствующее требование относится к универсальному оператору деления fixed-fixed.

Правила легальности

Этот абзац был удален.

Динамическая семантика

Операторы умножения и деления для вещественных типов имеют общепринятое значение. Для типов с плавающей точкой точность результата определяется точностью типа результата. Для типов с фиксированной точкой десятичного типа результат усекается к нулю, если математический результат находится между двумя кратными small конкретного типа результата (возможно, определенного контекстом); для обычных типов с фиксированной точкой, если математический результат находится между двумя кратными small, не определено, какой из двух является результатом.
Исключение Constraint_Error возбуждается целочисленным делением, rem и mod, если правым операндом является ноль. Аналогично, для вещественного типа T с T'Machine_Overflows True, деление на ноль вызывает Constraint_Error.
ПРИМЕЧАНИЯ
16 Для положительных A и B, A/B — это частное, а A rem B — это остаток при делении A на B. Следующие соотношения выполняются для оператора rem:
A rem (-B) = A rem B
(-A) rem B = -(A rem B)
17 Для любого целого со знаком K, справедливо следующее тождество:
A mod B = (A + K*B) mod B
Соотношения между целочисленным делением, остатком и модулем иллюстрируются следующей таблицей:
A B A/B A rem B A mod B A B A/B A rem B A mod B
10 5 2 0 0 -10 5 -2 0 0
11 5 2 1 1 -11 5 -2 -1 4
12 5 2 2 2 -12 5 -2 -2 3
13 5 2 3 3 -13 5 -2 -3 2
14 5 2 4 4 -14 5 -2 -4 1
A B A/B A rem B A mod B A B A/B A rem B A mod B

10 -5 -2 0 0 -10 -5 2 0 0
11 -5 -2 1 -4 -11 -5 2 -1 -1
12 -5 -2 2 -3 -12 -5 2 -2 -2
13 -5 -2 3 -2 -13 -5 2 -3 -3
14 -5 -2 4 -1 -14 -5 2 -4 -4

Примеры

Примеры выражений, включающих операторы умножения:
I : Integer := 1;
J : Integer := 2;
K : Integer := 3;
X : Real := 1.0; -- см. 3.5.7
Y : Real := 2.0;
F : Fraction := 0.25; -- см. 3.5.9
G : Fraction := 0.5;
Выражение Значение Тип результата

I*J 2 то же, что I и J, то есть Integer
K/J 1 то же, что K и J, то есть Integer
K mod J 1 то же, что K и J, то есть Integer

X/Y 0.5 то же, что X и Y, то есть Real
F/2 0.125 то же, что F, то есть Fraction

3*F 0.75 то же, что F, то есть Fraction
0.75*G 0.375 universal_fixed, неявно преобразуется
к любому типу с фиксированной точкой
Fraction(F*G) 0.125 Fraction, как указано преобразованием
Real(J)*Y 4.0 Real, тип обоих операндов после
преобразования J


Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API