4.5.5 Multiplying Operators
Static Semantics
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 is 
either zero, or 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
Name Resolution 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. Unless the predefined universal 
operator is identified using an expanded name with 
prefix 
denoting the package Standard, an explicit conversion is required on 
the result when using the above fixed-fixed multiplication operator if 
either operand is of a type having a user-defined primitive multiplication 
operator such that: 
 
it is declared immediately within the same declaration 
list as the type or any partial or incomplete view thereof; and
both of its formal parameters are of a fixed-point 
type. 
   A corresponding requirement applies to the universal 
fixed-fixed division operator.
Paragraph 20 was 
deleted. 
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. 
 
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 3.5.7
Y : Real := 2.0;
 
F : Fraction := 0.25;                 --
     see 3.5.9
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
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe