The
multiplying operators * (multiplication), / (division), **mod** (modulus),
and **rem** (remainder) are predefined for every specific integer
type *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)

{*AI05-0260-1*}
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*:

The following multiplication
and division operators, with an operand of the predefined type Integer,
are predefined for every specific fixed point type *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]:

Multiplication and
division between any two fixed point types are provided by the following
two predefined operators:

{*AI95-00364-01*}
{*AI95-00420-01*}
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:

{*AI05-0020-1*}
{*AI05-0209-1*}
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.

{*AI95-00364-01*}
{*AI95-00420-01*}
A corresponding requirement applies to the universal
fixed-fixed division operator.

On the other hand, X :=
A * B; is permitted by this rule, even if X, A, and B are all of different
fixed point types, since the expected type for the result of the multiplication
is the type of X, which is necessarily not *universal_fixed*.

{*AI95-00364-01*}
{*AI95-00420-01*}
We have made these into Name Resolution rules to
ensure that user-defined primitive fixed-fixed operators are not made
unusable due to the presence of these universal fixed-fixed operators.
But we do allow these operators to be used if prefixed by package Standard,
so that they can be used in the definitions of user-defined operators.

{*AI95-00364-01*}
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].

On the other hand, X :=
A * B; is permitted by this rule, even if X, A, and B are all of different
fixed point types, since the expected type for the result of the multiplication
is the type of X, which is necessarily not *universal_fixed*.

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)

(-A)

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

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

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;

J : Integer := 2;

K : Integer := 3;

X : Real := 1.0; --* see 3.5.7*

Y : Real := 2.0;

Y : Real := 2.0;

F : Fraction := 0.25; --* see 3.5.9*

G : Fraction := 0.5;

G : Fraction := 0.5;

I*J 2

K/J 1

K

X/Y 0.5

F/2 0.125

3*F 0.75

0.75*G 0.375

Fraction(F*G) 0.125

Real(J)*Y 4.0

{*AI95-00364-01*}
{*AI95-00420-01*}
The universal fixed-fixed multiplying
operators are now directly available (see below). Any attempt to use
user-defined fixed-fixed multiplying operators will be ambiguous with
the universal ones. The only way to use the user-defined operators is
to fully qualify them in a prefix call. This problem was not documented
during the design of Ada 95, and has been mitigated by Ada 2005.

Explicit conversion of the
result of multiplying or dividing two fixed point numbers is no longer
required, provided the context uniquely determines some specific fixed
point result type. This is to improve support for decimal fixed point,
where requiring explicit conversion on every fixed-fixed multiply or
divide was felt to be inappropriate.

The type *universal_fixed* is covered by
*universal_real*, so real literals and fixed point operands may
be multiplied or divided directly, without any explicit conversions required.

We have used the normal syntax for function
definition rather than a tabular format.

{*AI95-00364-01*}
We have changed the resolution
rules for the universal fixed-fixed multiplying operators to remove the
incompatibility with Ada 83 discussed above. The solution is to hide
the universal operators in some circumstances. As a result, some legal
Ada 95 programs will require the insertion of an explicit conversion
around a fixed-fixed multiply operator. This change is likely to catch
as many bugs as it causes, since it is unlikely that the user wanted
to use predefined operators when they had defined user-defined versions.

{*AI05-0020-1*}
{*AI05-0209-1*}
**Correction:** Wording was added to clarify
that *universal_fixed* "*" and "/" does not
apply if an appropriate operator is declared for a partial (or incomplete)
view of the designated type. Otherwise, adding a partial (or incomplete)
view could make some "*" and "/" operators ambiguous.

{*AI05-0260-1*}
**Correction:** The wording for the **mod**
operator was corrected so that a result of 0 does not have to have "the
sign of B" (which is impossible if B is negative).

Ada 2005 and 2012 Editions sponsored in part by **Ada-Europe**