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

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

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

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

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

Операторы умножения и деления для вещественных типов имеют стандартное значение. Для типов с плавающей запятой точность результата определяется точностью результата. Для типов с фиксированной точкой с десятичной запятой результат усекается к нулю, если математический результат находится между двумя кратными small конкретного типа результата (возможно, определяемого контекстом); для обычных типов с фиксированной точкой, если математический результат находится между двумя кратными small, то не определено, какой из двух является результатом.
Исключение Constraint_Error возникает при целочисленном делении, rem и mod, если правый операнд равен нулю. Аналогично, для вещественного типа T с T'Machine_Overflows True, деление на ноль вызывает Constraint_Error.
ПРИМЕЧАНИЯ
17 Для положительных A и B, A/B — частное, а A rem B — остаток, когда A делится на B. Следующие отношения выполняются оператором rem:
A rem (-B) = A rem B
(-A) rem B = -(A rem B)
18 Для любого целого со знаком 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