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

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.
ПРИМЕЧАНИЕ 1 Для положительных A и B, A/B — это частное, а A rem B — остаток от деления A на B. Следующие соотношения выполняются оператором rem:
A rem (-B) = A rem B
(-A) rem B = -(A rem B)
ПРИМЕЧАНИЕ 2 Для любого целого числа 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