A
fixed point type is either an ordinary fixed point type, or a decimal
fixed point type. The error bound of a fixed point
type is specified as an absolute value, called the *delta* of the
fixed point type.

decimal_fixed_point_definition ::=

**delta** *static_*expression **digits** *static_*expression [real_range_specification]

For a type defined by a fixed_point_definition,
the *delta* of the type is specified by the value of the expression
given after the reserved word **delta**; this expression
is expected to be of any real type. For
a type defined by a decimal_fixed_point_definition
(a *decimal* fixed point type), the number of significant decimal
digits for its first subtype (the *digits* of the first subtype)
is specified by the expression
given after the reserved word **digits**; this expression
is expected to be of any integer type.

In a fixed_point_definition
or digits_constraint,
the expressions
given after the reserved words **delta** and **digits** shall be
static; their values shall be positive.

{*AI95-00100-01*}
The set of values of a fixed point type comprise
the integral multiples of a number called the *small* of the type.
The *machine numbers* of a fixed point type are the values of the
type that can be represented exactly in every unconstrained variable
of the type. For a type defined by an ordinary_fixed_point_definition
(an *ordinary* fixed point type), the *small* may be specified
by an attribute_definition_clause
(see 13.3); if so specified, it shall be no
greater than the *delta* of the type. If not specified, the *small*
of an ordinary fixed point type is an implementation-defined power of
two less than or equal to the *delta*.

For a decimal fixed point type, the *small*
equals the *delta*; the *delta* shall be a power of 10. If
a real_range_specification
is given, both bounds of the range shall be in the range –(10***digits*–1)**delta*
.. +(10***digits*–1)**delta*.

A fixed_point_definition
is illegal if the implementation does not support a fixed point type
with the given *small* and specified range or *digits*.

For a subtype_indication
with a digits_constraint,
the subtype_mark
shall denote a decimal fixed point subtype.

The base range (see 3.5)
of a fixed point type is symmetric around zero, except possibly for an
extra negative value in some implementations.

An
ordinary_fixed_point_definition
defines an ordinary fixed point type whose base range includes at least
all multiples of *small* that are between the bounds specified in
the real_range_specification.
The base range of the type does not necessarily include the specified
bounds themselves. An ordinary_fixed_point_definition
also defines a constrained first subtype of the type, with each bound
of its range given by the closer to zero of:

the value of the conversion to the fixed point
type of the corresponding expression
of the real_range_specification;

the corresponding bound of the base range.

A decimal_fixed_point_definition
defines a decimal fixed point type whose base range includes at least
the range –(10***digits*–1)**delta* .. +(10***digits*–1)**delta*.
A decimal_fixed_point_definition
also defines a constrained first subtype of the type. If a real_range_specification
is given, the bounds of the first subtype are given by a conversion of
the values of the expressions
of the real_range_specification.
Otherwise, the range of the first subtype is –(10***digits*–1)**delta*
.. +(10***digits*–1)**delta*.

The elaboration of a fixed_point_definition
creates the fixed point type and its first subtype.

For a digits_constraint
on a decimal fixed point subtype with a given *delta*, if it does
not have a range_constraint,
then it specifies an implicit range –(10***D*–1)**delta*
.. +(10***D*–1)**delta*, where *D* is the value
of the expression.
A digits_constraint
is *compatible* with a decimal fixed point subtype if the value
of the expression
is no greater than the *digits* of the subtype, and if it specifies
(explicitly or implicitly) a range that is compatible with the subtype.

Consider the following
example:

The compatibility rule implies that the digits_constraint
"**digits** 6" specifies an implicit range of "–9999.99 99.9999
.. 9999.99 99.9999".
Thus, "**digits** 6" is not compatible with the constraint
of D, but "**digits** 6 range 0.00 .. 9999.99" is compatible.

{*AI95-00114-01*}
A value of a scalar type belongs to a constrained subtype of the type
if it belongs to the range of the subtype. Attributes like Digits and
Delta have no effect affect
on this fundamental rule. So the obsolescent forms of digits_constraints
and delta_constraints
that are called “accuracy constraints” in RM83 don't really
represent constraints on the values of the subtype, but rather primarily
affect compatibility of the “constraint” with the subtype
being “constrained.” In this sense, they might better be
called “subtype assertions” rather than “constraints.”

Note that the digits_constraint
on a decimal fixed point subtype is a combination of an assertion about
the *digits* of the subtype being further constrained, and a constraint
on the range of the subtype being defined, either explicit or implicit.

The elaboration of a digits_constraint
consists of the elaboration of the range_constraint,
if any. If a range_constraint
is given, a check is made that the bounds of the range are both in the
range –(10***D*–1)**delta* .. +(10***D*–1)**delta*,
where *D* is the value of the (static) expression
given after the reserved word **digits**. If this
check fails, Constraint_Error is raised.

The implementation shall support at least 24 bits
of precision (including the sign bit) for fixed point types.

Implementations are permitted to support only *small*s
that are a power of two. In particular, all decimal fixed point type
declarations can be disallowed. Note however that conformance with the
Information Systems Annex requires support for decimal *small*s,
and decimal fixed point type declarations with *digits* up to at
least 18.

NOTES

41 The base
range of an ordinary fixed point type need not include the specified
bounds themselves so that the range specification can be given in a natural
way, such as:

With 2's complement hardware, such a type could have
a signed 16-bit representation, using 1 bit for the sign and 15 bits
for fraction, resulting in a base range of –1.0 .. 1.0–2.0**(–15).

-- *A pure fraction which requires all the available*

--*space in a word can be declared as the type Fraction:*

**type** Fraction **is** **delta** System.Fine_Delta **range** -1.0 .. 1.0;

--*Fraction'Last = 1.0 – System.Fine_Delta*

--

--

--

In Ada 95, S'Small always
equals S'Base'Small, so if an implementation chooses a *small* for
a fixed point type smaller than required by the *delta*, the value
of S'Small in Ada 95 might not be the same as it was in Ada 83.

{*AI05-0005-1*}
Decimal fixed point types are new, though their capabilities
are essentially similar to that available in Ada 83 with a fixed point
type whose *small* equals its *delta* and
both are equals a power of 10. However,
in the Information Systems Annex, additional requirements are placed
on the support of decimal fixed point types (e.g. a minimum of 18 digits
of precision).

The syntax rules for fixed_point_constraint
and fixed_accuracy_definition are removed.
The syntax rule for fixed_point_definition
is new. A syntax rule for delta_constraint
is included in the Obsolescent features (to be compatible with Ada 83's
fixed_point_constraint).

{*AI95-00100-01*}
Added wording to define the machine numbers of
fixed point types; this is needed by the static evaluation rules.

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