The
following *representation-oriented attributes* are defined for every
subtype S of a floating point type *T*.

S'Machine_Radix

Yields the radix of the hardware representation of the type

The values of other representation-oriented
attributes of a floating point subtype, and of the “primitive function”
attributes of a floating point subtype described later, are defined in
terms of a particular representation of nonzero values called the *canonical
form*. The canonical form (for the type *T*) is the form

±*mantissa*
· *T*'Machine_Radix^{exponent}

where

±

where

S'Machine_Mantissa

Yields the largest value of

S'Machine_Emin

Yields the smallest (most negative) value of

S'Machine_Emax

Yields the largest (most positive) value of

S'Denorm

Yields the value True if every
value expressible in the form

±*mantissa*
· *T*'Machine_Radix^{T'Machine_Emin}

where*mantissa* is a nonzero *T*'Machine_Mantissa-digit fraction
in the number base *T*'Machine_Radix, the first digit of which is
zero, is a machine number (see 3.5.7) of
the type *T*; yields the value False otherwise. The value of this
attribute is of the predefined type Boolean.

±

where

The values described by the formula
in the definition of S'Denorm are called *denormalized numbers*.
A nonzero machine number that is not a denormalized
number is a *normalized number*. A
normalized number *x* of a given type
*T* is said to be *represented in canonical form* when it is
expressed in the canonical form (for the type *T*) with a *mantissa*
having *T*'Machine_Mantissa digits; the resulting form is the *canonical-form
representation* of *x*.

S'Machine_Rounds

Yields the value True if rounding is performed on inexact results of every predefined operation that yields a result of the type

S'Model_Mantissa = S'Machine_Mantissa, so
that operand preperturbation never occurs;

when the exact mathematical result is not
a machine number, the result of a predefined operation must be the nearer
of the two adjacent machine numbers.

Technically, this attribute should yield False
when extended registers are used, since a few computed results will cross
over the half-way point as a result of double rounding, if and when a
value held in an extended register has to be reduced in precision to
that of the machine numbers. It does not seem desirable to preclude the
use of extended registers when S'Machine_Rounds could otherwise be True.

S'Machine_Overflows

Yields the value True if overflow and divide-by-zero are detected and reported by raising Constraint_Error for every predefined operation that yields a result of the type

S'Signed_Zeros

Yields the value True if the hardware representation for the type

the normalized exponent of zero is (by convention)
zero;

for nonzero *x*,
the normalized exponent of *x* is the
unique integer *k* such that *T*'Machine_Radix^{k–1}
≤ |*x*| < *T*'Machine_Radix^{k}.

The normalized exponent of a denormalized number
is less than the value of *T*'Machine_Emin.

The
following *primitive function attributes* are defined for any subtype
S of a floating point type *T*.

S'Exponent

The function yields the normalized exponent
of *X*.

S'Fraction

The function yields the value *X*
· *T*'Machine_Radix^{–k},
where *k* is the normalized exponent
of *X*. A zero result[, which can only occur when *X* is zero,]
has the sign of *X*.

S'Compose

Let *v*
be the value *Fraction* · *T*'Machine_Radix^{Exponent–k},
where *k* is the normalized exponent
of *Fraction*. If *v* is a machine
number of the type *T*, or if |*v*|
≥ *T*'Model_Small,
the function yields *v*; otherwise, it
yields either one of the machine numbers of the type *T* adjacent
to *v*. Constraint_Error
is optionally raised if *v* is outside
the base range of S. A zero result has the sign of *Fraction* when
S'Signed_Zeros is True.

S'Scaling

Let *v*
be the value *X* · *T*'Machine_Radix^{Adjustment}.
If *v* is a machine number of the type
*T*, or if |*v*| ≥ *T*'Model_Small,
the function yields *v*; otherwise, it
yields either one of the machine numbers of the type *T* adjacent
to *v*. Constraint_Error
is optionally raised if *v* is outside
the base range of S. A zero result has the sign of *X* when S'Signed_Zeros
is True.

S'Floor

The function yields the value *Floor*(*X*),
i.e., the largest (most positive) integral value less than or equal to
*X*. When *X* is zero, the result has the sign of *X*;
a zero result otherwise has a positive sign.

S'Ceiling

The function yields the value *Ceiling*(*X*),
i.e., the smallest (most negative) integral value greater than or equal
to *X*. When *X* is zero, the result has the sign of *X*;
a zero result otherwise has a negative sign when S'Signed_Zeros is True.

S'Rounding

The function yields the integral value
nearest to *X*, rounding away from zero if *X* lies exactly
halfway between two integers. A zero result has the sign of *X*
when S'Signed_Zeros is True.

S'Unbiased_Rounding

The function yields the integral value
nearest to *X*, rounding toward the even integer if *X* lies
exactly halfway between two integers. A zero result has the sign of *X*
when S'Signed_Zeros is True.

S'Machine_Rounding

The function yields
the integral value nearest to *X*. If *X* lies exactly halfway
between two integers, one of those integers is returned, but which of
them is returned is unspecified. A zero result has the sign of *X*
when S'Signed_Zeros is True. This function provides access to the rounding
behavior which is most efficient on the target processor.

S'Truncation

The function yields the value *Ceiling*(*X*)
when *X* is negative, and *Floor*(*X*)
otherwise. A zero result has the sign of *X* when S'Signed_Zeros
is True.

S'Remainder

For nonzero *Y*,
let *v* be the value *X*
– *n* · *Y*,
where *n* is the integer nearest to the
exact value of *X*/*Y*;
if |*n* – *X*/*Y*|
= 1/2, then *n* is chosen to be even.
If *v* is a machine number of the type
*T*, the function yields *v*; otherwise,
it yields zero. Constraint_Error
is raised if *Y* is zero. A zero result has the sign of *X*
when S'Signed_Zeros is True.

S'Adjacent

If *Towards*
= *X*, the function yields *X*;
otherwise, it yields the machine number of the type *T* adjacent
to *X* in the direction of *Towards*, if that machine number
exists. If the result would be
outside the base range of S, Constraint_Error is raised. When *T*'Signed_Zeros
is True, a zero result has the sign of *X*. When *Towards*
is zero, its sign has no bearing on the result.

S'Copy_Sign

If the value of *Value*
is nonzero, the function yields a result whose magnitude is that of *Value*
and whose sign is that of *Sign*; otherwise, it yields the value
zero. Constraint_Error is optionally
raised if the result is outside the base range of S. A zero result has
the sign of *Sign* when S'Signed_Zeros is True.

S'Leading_Part

Let *v*
be the value *T*'Machine_Radix^{k–Radix_Digits},
where *k* is the normalized exponent
of *X*. The function yields the value

Constraint_Error
is raised when *Radix_Digits* is zero or negative. A zero result[,
which can only occur when *X* is zero,] has the sign of *X*.

S'Machine

If *X* is a machine
number of the type *T*, the function yields *X*; otherwise,
it yields the value obtained by rounding or truncating *X* to either
one of the adjacent machine numbers of the type *T*. Constraint_Error
is raised if rounding or truncating *X* to the precision of the
machine numbers results in a value outside the base range of S. A zero
result has the sign of *X* when S'Signed_Zeros is True.

S'Model_Mantissa

If the Numerics Annex is not supported, this attribute yields an implementation defined value that is greater than or equal to

S'Model_Emin

If the Numerics Annex is not
supported, this attribute yields an implementation defined value that
is greater than or equal to the value of *T*'Machine_Emin. See G.2.2
for further requirements that apply to implementations supporting the
Numerics Annex. The value of this attribute is of the type *universal_integer*.

S'Model_Epsilon

Yields the value

S'Model_Small

Yields the value

S'Model

If the Numerics Annex is not supported,
the meaning of this attribute is implementation defined; see G.2.2
for the definition that applies to implementations supporting the Numerics
Annex.

S'Safe_First

Yields the lower bound of the
safe range (see 3.5.7) of the type *T*.
If the Numerics Annex is not supported, the value of this attribute is
implementation defined; see G.2.2 for the
definition that applies to implementations supporting the Numerics Annex.
The value of this attribute is of the type *universal_real*.

S'Safe_Last

Yields the upper bound of the
safe range (see 3.5.7) of the type *T*.
If the Numerics Annex is not supported, the value of this attribute is
implementation defined; see G.2.2 for the
definition that applies to implementations supporting the Numerics Annex.
The value of this attribute is of the type *universal_real*.

The Epsilon and Mantissa
attributes of floating point types are removed from the language and
replaced by Model_Epsilon and Model_Mantissa, which may have different
values (as a result of changes in the definition of model numbers); the
replacement of one set of attributes by another is intended to convert
what would be an inconsistent change into an incompatible change.

The Emax, Small, Large, Safe_Emax, Safe_Small,
and Safe_Large attributes of floating point types are removed from the
language. Small and Safe_Small are collectively replaced by Model_Small,
which is functionally equivalent to Safe_Small, though it may have a
slightly different value. The others are collectively replaced by Safe_First
and Safe_Last. Safe_Last is functionally equivalent to Safe_Large, though
it may have a different value; Safe_First is comparable to the negation
of Safe_Large but may differ slightly from it as well as from the negation
of Safe_Last. Emax and Safe_Emax had relatively few uses in Ada 83; T'Safe_Emax
can be computed in the revised language as Integer'Min(T'Exponent(T'Safe_First),
T'Exponent(T'Safe_Last)).

Implementations are encouraged to eliminate
the incompatibilities discussed here by retaining the old attributes,
during a transition period, in the form of implementation-defined attributes
with their former values.

The Model_Emin attribute
is new. It is conceptually similar to the negation of Safe_Emax attribute
of Ada 83, adjusted for the fact that the model numbers now have the
hardware radix. It is a fundamental determinant, along with Model_Mantissa,
of the set of model numbers of a type (see G.2.1).

The Denorm and Signed_Zeros attributes are new,
as are all of the primitive function attributes.

{*AI95-00388-01*}
The Machine_Rounding attribute
is new.

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