-
The multiplying operators * (multiplication), / (division), mod
(modulus), and rem (remainder) are predefined for every specific integer
type 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
-
Signed integer multiplication has its conventional meaning.
-
Signed integer division and remainder are defined by the relation:
-
A = (A/B)*B + (A rem B)
-
where (A rem B) has the sign of A and an absolute value less than the
absolute value of B. Signed integer division satisfies the identity:
-
(-A)/B = -(A/B) = A/(-B)
-
The signed integer modulus operator is defined such that the result of A
mod B has the sign of B and an absolute value less than the absolute
value of B; in addition, for some signed integer value N, this result
satisfies the relation:
-
A = B*N + (A mod B)
-
The multiplying operators on modular types are defined in terms of the
corresponding signed integer operators, followed by a reduction modulo
the modulus if the result is outside the base range of the type (which
is only possible for the "*" operator).
-
Multiplication and division operators are predefined for every specific
floating point type T:
-
function "*"(Left, Right : T) return T
function "/"(Left, Right : T) return T
-
The following multiplication and division operators, with an operand of
the predefined type Integer, are predefined for every specific fixed
point type T:
-
function "*"(Left : T; Right : Integer) return T
function "*"(Left : Integer; Right : T) return T
function "/"(Left : T; Right : Integer) return T
-
All of the above multiplying operators are usable with an operand of an
appropriate universal numeric type. The following additional multiplying
operators for root_real are predefined, and are usable when both
operands are of an appropriate universal or root numeric type, and the
result is allowed to be of type root_real, as in a number_declaration:
-
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
-
Multiplication and division between any two fixed point types are
provided by the following two predefined operators:
-
function "*"(Left, Right : universal_fixed) return universal_fixed
function "/"(Left, Right : universal_fixed) return universal_fixed
Legality Rules
-
The above two fixed-fixed multiplying operators shall not be used in a
context where the expected type for the result is itself universal_fixed
-- the context has to identify some other numeric type to which the
result is to be converted, either explicitly or implicitly.
Dynamic Semantics
-
The multiplication and division operators for real types have their
conventional meaning. For floating point types, the accuracy of the
result is determined by the precision of the result type. For decimal
fixed point types, the result is truncated toward zero if the
mathematical result is between two multiples of the small of the
specific result type (possibly determined by context); for ordinary
fixed point types, if the mathematical result is between two multiples
of the small, it is unspecified which of the two is the result.
-
The exception Constraint_Error is raised by integer division, rem, and
mod if the right operand is zero. Similarly, for a real type T with
T'Machine_Overflows True, division by zero raises Constraint_Error.
NOTES
-
(17) For positive A and B, A/B is the quotient and A rem B is the
remainder when A is divided by B. The following relations are satisfied
by the rem operator:
-
A rem (-B) = A rem B
(-A) rem B = -(A rem B)
-
(18) For any signed integer K, the following identity holds:
-
A mod B = (A + K*B) mod B
-
The relations between signed integer division, remainder, and modulus
are illustrated by the following table:
-
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
Examples
-
Examples of expressions involving multiplying operators:
-
I : Integer := 1;
J : Integer := 2;
K : Integer := 3;
-
X : Real := 1.0; -- See section 3.5.7 Floating Point Types
Y : Real := 2.0;
-
F : Fraction := 0.25; -- See section 3.5.9 Fixed Point Types
G : Fraction := 0.5;
-
Expression Value Result Type
I*J 2 same as I and J, that is, Integer
K/J 1 same as K and J, that is, Integer
K mod J 1 same as K and J, that is, Integer
X/Y 0.5 same as X and Y, that is, Real
F/2 0.125 same as F, that is, Fraction
3*F 0.75 same as F, that is, Fraction
0.75*G 0.375 universal_fixed, implicitly convertible
to any fixed point type
Fraction(F*G) 0.125 Fraction, as stated by the conversion
Real(J)*Y 4.0 Real, the type of both operands after
conversion of J