3.5 Scalar Types
This Reference Manual output has not been verified, and may contain omissions or errors. Report any problems on the tracking issue
Scalar types comprise enumeration types, integer types, and real types. Enumeration types and integer types are called discrete types; each value of a discrete type has a position number which is an integer value. Integer types and real types are called numeric types. [All scalar types are ordered, that is, all relational operators are predefined for their values.]
Syntax
2range_constraint
::=
range range
3range
::=
range_attribute_reference
| simple_expression
.. simple_expression
simple_expression
s rather than more general expression
s because ranges appear in membership tests and other contexts where expression
.. expression
would be ambiguous. A range has a lower bound and an upper bound and specifies a subset of the values of some scalar type (the type of the range). A range with lower bound L and upper bound R is described by “L .. R”. If R is less than L, then the range is a null range, and specifies an empty set of values. Otherwise, the range specifies the values of the type from the lower bound to the upper bound, inclusive. A value belongs to a range if it is of the type of the range, and is in the subset of values specified by the range. A value satisfies a range constraint if it belongs to the associated range. One range is included in another if all values that belong to the first range also belong to the second.
Name Resolution Rules
5For a subtype_indication
containing a range_constraint
, either directly or as part of some other scalar_constraint
, the type of the range
shall resolve to that of the type determined by the subtype_mark
of the subtype_indication
. For a range
of a given type, the simple_expression
s of the range
(likewise, the simple_expression
s of the equivalent range
for a range_attribute_reference
) are expected to be of the type of the range
.
constraint
s only appear within subtype_indication
s; things that look like constraints that appear in type declarations are called something else like real_range_specification
s.range
shall resolve to ...” rather than “the expected type for the range
is ...” We then use “expected type” for the bounds. If we used “expected” at both points, there would be an ambiguity, since one could apply the rules of 8.6 either on determining the type of the range, or on determining the types of the individual bounds. It is clearly important to allow one bound to be of a universal type, and the other of a specific type, so we need to use “expected type” for the bounds. Hence, we used “shall resolve to” for the type of the range as a whole. There are other situations where “expected type” is not quite right, and we use “shall resolve to” instead. Static Semantics
6The base range of a scalar type is the range of finite values of the type that can be represented in every unconstrained object of the type; it is also the range supported at a minimum for intermediate values during the evaluation of expressions involving predefined operators of the type.
[A constrained scalar subtype is one to which a range constraint applies.] The range of a constrained scalar subtype is the range associated with the range constraint of the subtype. The range of an unconstrained scalar subtype is the base range of its type.
Dynamic Semantics
8A range is compatible with a scalar subtype if and only if it is either a null range or each bound of the range belongs to the range of the subtype. A range_constraint
is compatible with a scalar subtype if and only if its range is compatible with the subtype.
range_constraint
s (explicit or implicit) impose conditions on the values of a scalar subtype. The other scalar_constraint
s, digits_constraint
s and delta_constraint
s impose conditions on the subtype denoted by the subtype_mark
in a subtype_indication
, but don't impose a condition on the values of the subtype being defined. Therefore, a scalar subtype is not called constrained if all that applies to it is a digits_constraint
. Decimal subtypes are subtle, because a digits_constraint
without a range_constraint
nevertheless includes an implicit range_constraint
. The elaboration of a range_constraint
consists of the evaluation of the range
. The evaluation of a range
determines a lower bound and an upper bound. If simple_expression
s are given to specify bounds, the evaluation of the range
evaluates these simple_expression
s in an arbitrary order, and converts them to the type of the range
. If a range_attribute_reference
is given, the evaluation of the range
consists of the evaluation of the range_attribute_reference
.
Attributes
For every scalar subtype S, the following attributes are defined:
S'First
- S'First denotes the lower bound of the range of S. The value of this attribute is of the type of S.
S'Last
- S'Last denotes the upper bound of the range of S. The value of this attribute is of the type of S.
S'Range
- S'Range is equivalent to the
range
S'First .. S'Last. 15
S'Base- S'Base denotes an unconstrained subtype of the type of S. This unconstrained subtype is called the base subtype of the type.
S'Min- S'Min denotes a function with the following specification:
function S'Min(Left, Right : S'Base)
return S'Base
- The function returns the lesser of the values of the two parameters.
attribute_reference
is not permitted as the designator of a user-defined function, nor can its formal parameters be anonymous. S'Max
- S'Max denotes a function with the following specification:
function S'Max(Left, Right : S'Base)
return S'Base
- The function returns the greater of the values of the two parameters.
S'Succ- S'Succ denotes a function with the following specification:
function S'Succ(Arg : S'Base)
return S'Base
- For an enumeration type, the function returns the value whose position number is one more than that of the value of Arg; Constraint_Error is raised if there is no such value of the type. For an integer type, the function returns the result of adding one to the value of Arg. For a fixed point type, the function returns the result of adding small to the value of Arg. For a floating point type, the function returns the machine number (as defined in 3.5.7) immediately above the value of Arg; Constraint_Error is raised if there is no such machine number.
S'Pred
- S'Pred denotes a function with the following specification:
function S'Pred(Arg : S'Base)
return S'Base
- For an enumeration type, the function returns the value whose position number is one less than that of the value of Arg; Constraint_Error is raised if there is no such value of the type. For an integer type, the function returns the result of subtracting one from the value of Arg. For a fixed point type, the function returns the result of subtracting small from the value of Arg. For a floating point type, the function returns the machine number (as defined in 3.5.7) immediately below the value of Arg; Constraint_Error is raised if there is no such machine number.
S'Wide_Wide_Image
S'Wide_Image
- Paragraphs 28 through 37 were moved to 4.10, “Image Attributes” .
S'Image-
S'Wide_Wide_Width
- S'Wide_Wide_Width denotes the maximum length of a Wide_Wide_String returned by S'Wide_Wide_Image over all values of the subtype S, assuming a default implementation of S'Put_Image. It denotes zero for a subtype that has a null range. Its type is universal_integer.
S'Wide_Width- S'Wide_Width denotes the maximum length of a Wide_String returned by S'Wide_Image over all values of the subtype S, assuming a default implementation of S'Put_Image. It denotes zero for a subtype that has a null range. Its type is universal_integer.
S'Width- S'Width denotes the maximum length of a String returned by S'Image over all values of the subtype S, assuming a default implementation of S'Put_Image. It denotes zero for a subtype that has a null range. Its type is universal_integer.
S'Wide_Wide_Value- S'Wide_Wide_Value denotes a function with the following specification:
function S'Wide_Wide_Value(Arg : Wide_Wide_String)
return S'Base
- This function returns a value given an image of the value as a Wide_Wide_String, ignoring any leading or trailing spaces.
- For the evaluation of a call on S'Wide_Wide_Value for an enumeration subtype S, if the sequence of characters of the parameter (ignoring leading and trailing spaces) has the syntax of an enumeration literal and if it corresponds to a literal of the type of S (or corresponds to the result of S'Wide_Wide_Image for a nongraphic character of the type), the result is the corresponding enumeration value; otherwise, Constraint_Error is raised.
- For the evaluation of a call on S'Wide_Wide_Value for an integer subtype S, if the sequence of characters of the parameter (ignoring leading and trailing spaces) has the syntax of an integer literal, with an optional leading sign character (plus or minus for a signed type; only plus for a modular type), and the corresponding numeric value belongs to the base range of the type of S, then that value is the result; otherwise, Constraint_Error is raised.
assignment_statement
like "X := <numeric_literal>;" that the value of the numeric-literal be in X's base range (at compile time), so it seems unfriendly and confusing to have a different range allowed for 'Value. Furthermore, for modular types, without the requirement for being in the base range, 'Value would have to handle arbitrarily long literals (since overflow never occurs for modular types). - For the evaluation of a call on S'Wide_Wide_Value for a real subtype S, if the sequence of characters of the parameter (ignoring leading and trailing spaces) has the syntax of one of the following:
numeric_literal
39.8/2numeral
.[exponent
] 39.9/2- .
numeral
[exponent
] 39.10/2 base
#based_numeral
.#[exponent
] 39.11/2base
#.based_numeral
#[exponent
]
- with an optional leading sign character (plus or minus), and if the corresponding numeric value belongs to the base range of the type of S, then that value is the result; otherwise, Constraint_Error is raised. The sign of a zero value is preserved (positive if none has been specified) if S'Signed_Zeros is True.
S'Wide_Value- S'Wide_Value denotes a function with the following specification:
function S'Wide_Value(Arg : Wide_String)
return S'Base
- This function returns a value given an image of the value as a Wide_String, ignoring any leading or trailing spaces.
- For the evaluation of a call on S'Wide_Value for an enumeration subtype S, if the sequence of characters of the parameter (ignoring leading and trailing spaces) has the syntax of an enumeration literal and if it corresponds to a literal of the type of S (or corresponds to the result of S'Wide_Image for a value of the type, assuming a default implementation of S'Put_Image), the result is the corresponding enumeration value; otherwise, Constraint_Error is raised. For a numeric subtype S, the evaluation of a call on S'Wide_Value with Arg of type Wide_String is equivalent to a call on S'Wide_Wide_Value for a corresponding Arg of type Wide_Wide_String.
- Paragraphs 44 through 51 were moved to Wide_Wide_Value.
S'Value- S'Value denotes a function with the following specification:
function S'Value(Arg : String)
return S'Base
- This function returns a value given an image of the value as a String, ignoring any leading or trailing spaces.
- For the evaluation of a call on S'Value for an enumeration subtype S, if the sequence of characters of the parameter (ignoring leading and trailing spaces) has the syntax of an enumeration literal and if it corresponds to a literal of the type of S (or corresponds to the result of S'Image for a value of the type, assuming a default implementation of S'Put_Image), the result is the corresponding enumeration value; otherwise, Constraint_Error is raised. For a numeric subtype S, the evaluation of a call on S'Value with Arg of type String is equivalent to a call on S'Wide_Wide_Value for a corresponding Arg of type Wide_Wide_String.
X'Wide_Wide_Image
Implementation Permissions
56/2An implementation may extend the Wide_Wide_Value, [Wide_Value, Value, Wide_Wide_Image, Wide_Image, and Image] attributes of a floating point type to support special values such as infinities and NaNs.
An implementation may extend the Wide_Wide_Value, Wide_Value, and Value attributes of a character type to accept strings of the form “Hex_hhhhhhhh” (ignoring case) for any character (not just the ones for which Wide_Wide_Image would produce that form — see 3.5.2), as well as three-character strings of the form “'X'”, where X is any character, including nongraphic characters.
Static Semantics
56.2/3For a scalar type, the following language-defined representation aspect may be specified with an aspect_specification
(see 13.1.1):
Default_Value
- This aspect shall be specified by a static expression, and that expression shall be explicit, even if the aspect has a boolean type. Default_Value shall be specified only on a
full_type_declaration
.
If a derived type inherits a boolean Default_Value aspect, the aspect may be specified to have any value for the derived type. If a derived type T does not inherit a Default_Value aspect, it shall not specify such an aspect if it inherits a primitive subprogram that has a parameter of type T of mode out.
Name Resolution Rules
56.5/3The expected type for the expression
specified for the Default_Value aspect is the type defined by the full_type_declaration
on which it appears.
Examples
60Examples of ranges:
-10 .. 10
X .. X + 1
0.0 .. 2.0*Pi
Red .. Green -- see 3.5.1
1 .. 0 -- a null range
Table'Range -- a range attribute reference (see 3.6)
62Examples of range constraints:
range -999.0 .. +999.0
range S'First+1 .. S'Last-1
Incompatibilities With Ada 83
prefix
.Extensions to Ada 83
subtype_mark
is permitted. S'Base'First .. S'Base'Last is the base range of the type. Using an attribute_definition_clause
, one cannot specify any subtype-specific attributes for the subtype denoted by S'Base (the base subtype).Wording Changes from Ada 83
range_attribute_reference
since it is now syntactically distinguished from other attribute references.Extensions to Ada 95
Wording Changes from Ada 95
Inconsistencies With Ada 2005
Extensions to Ada 2005
Extensions to Ada 2012
3.5.1 Enumeration Types
1[ An enumeration_type_definition
defines an enumeration type.]
Syntax
2enumeration_type_definition
::=
(enumeration_literal_specification
{, enumeration_literal_specification
})
3enumeration_literal_specification
::=
defining_identifier
| defining_character_literal
4defining_character_literal
::=
character_literal
Legality Rules
5/3The defining_identifier
s in upper case [and the defining_character_literal
s] listed in an enumeration_type_definition
shall be distinct.
Static Semantics
6/3Each enumeration_literal_specification
is the explicit declaration of the corresponding enumeration literal: it declares a parameterless function, whose defining name is the defining_identifier
or defining_character_literal
, and whose result subtype is the base subtype of the enumeration type.
enumeration_type_definition
; a body is not permitted for it, and it never fails the Elaboration_Check when called. expression
of a case statement, due to the full coverage requirement based on the nominal subtype. Each enumeration literal corresponds to a distinct value of the enumeration type, and to a distinct position number. The position number of the value of the first listed enumeration literal is zero; the position number of the value of each subsequent enumeration literal is one more than that of its predecessor in the list.
[The predefined order relations between values of the enumeration type follow the order of corresponding position numbers.]
[ If the same defining_identifier
or defining_character_literal
is specified in more than one enumeration_type_definition
, the corresponding enumeration literals are said to be overloaded. At any place where an overloaded enumeration literal occurs in the text of a program, the type of the enumeration literal has to be determinable from the context (see 8.6).]
Dynamic Semantics
10The elaboration of an enumeration_type_definition
creates the enumeration type and its first subtype, which is constrained to the base range of the type.
When called, the parameterless function associated with an enumeration literal returns the corresponding value of the enumeration type.
Examples
13Examples of enumeration types and subtypes:
type Day is (Mon, Tue, Wed, Thu, Fri, Sat, Sun);
type Month_Name is (January, February, March, April, May, June, July,
August, September, October, November, December);
type Suit is (Clubs, Diamonds, Hearts, Spades);
type Gender is (M, F);
type Level is (Low, Medium, Urgent);
type Color is (White, Red, Yellow, Green, Blue, Brown, Black);
type Light is (Red, Amber, Green); -- Red and Green are overloaded
15type Hexa is ('A', 'B', 'C', 'D', 'E', 'F');
type Mixed is ('A', 'B', '*', B, None, '?', '%');
16subtype Weekday is Day range Mon .. Fri;
subtype Major is Suit range Hearts .. Spades;
subtype Rainbow is Color range Red .. Blue; -- the Color Red, not the Light
Wording Changes from Ada 83
defining_character_literal
is new. It is used for the defining occurrence of a character_literal
, analogously to defining_identifier
. Usage occurrences use the name
or selector_name
syntactic categories.Incompatibilities With Ada 2005
Wording Changes from Ada 2005
3.5.2 Character Types
Static Semantics
1An enumeration type is said to be a character type if at least one of its enumeration literals is a character_literal
.
The predefined type Character is a character type whose values correspond to the 256 code points of Row 00 (also known as Latin-1) of the ISO/IEC 10646:2017 Basic Multilingual Plane (BMP). Each of the graphic characters of Row 00 of the BMP has a corresponding character_literal
in Character. Each of the nongraphic characters of Row 00 has a corresponding language-defined name, which is not usable as an enumeration literal, but which is usable with the attributes Image, Wide_Image, Wide_Wide_Image, Value, Wide_Value, and Wide_Wide_Value; these names are given in the definition of type Character in A.1, “The Package Standard”, but are set in italics.
The predefined type Wide_Character is a character type whose values correspond to the 65536 code points of the ISO/IEC 10646:2017 Basic Multilingual Plane (BMP). Each of the graphic characters of the BMP has a corresponding character_literal
in Wide_Character. The first 256 values of Wide_Character have the same character_literal
or language-defined name as defined for Character. Each of the graphic_character
s has a corresponding character_literal
.
The predefined type Wide_Wide_Character is a character type whose values correspond to the 2147483648 code points of the ISO/IEC 10646:2017 character set. Each of the graphic_character
s has a corresponding character_literal
in Wide_Wide_Character. The first 65536 values of Wide_Wide_Character have the same character_literal
or language-defined name as defined for Wide_Character.
The characters whose code point is larger than 16#FF# and which are not graphic_character
s have language-defined names which are formed by appending to the string "Hex_" the representation of their code point in hexadecimal as eight extended digits. As with other language-defined names, these names are usable only with the attributes (Wide_)Wide_Image and (Wide_)Wide_Value; they are not usable as enumeration literals.
Original Paragraphs 4 and 5 were deleted.
enumeration_representation_clause
as explained in subclause 13.4. Examples
10Example of a character type:
type Roman_Digit is ('I', 'V', 'X', 'L', 'C', 'D', 'M');
Inconsistencies With Ada 83
Incompatibilities With Ada 83
'a' = 'b'
Extensions to Ada 83
Inconsistencies With Ada 95
character_literal
of a nongraphic character, while Ada 95 would have accepted it. Similarly, the result of Wide_Character'Wide_Image will change for such nongraphic characters.Extensions to Ada 95
Wording Changes from Ada 95
Wording Changes from Ada 2005
3.5.3 Boolean Types
Static Semantics
1There is a predefined enumeration type named Boolean, [declared in the visible part of package Standard]. It has the two enumeration literals False and True ordered with the relation False < True. Any descendant of the predefined type Boolean is called a boolean type.
3.5.4 Integer Types
1An integer_type_definition
defines an integer type; it defines either a signed integer type, or a modular integer type. The base range of a signed integer type includes at least the values of the specified range. A modular type is an integer type with all arithmetic modulo a specified positive modulus; such a type corresponds to an unsigned type with wrap-around semantics.
Syntax
2integer_type_definition
::=
signed_integer_type_definition
| modular_type_definition
3signed_integer_type_definition
::=
range static_simple_expression
.. static_simple_expression
range_constraint
, because it is rather different — not only is it required to be static, but the associated overload resolution rules are different than for normal range constraints. A similar comment applies to real_range_specification
. This used to be integer_range_specification
but when we added support for modular types, it seemed overkill to have three levels of syntax rules, and just calling these signed_integer_range_specification
and modular_range_specification
loses the fact that they are defining different classes of types, which is important for the generic type matching rules. modular_type_definition
::=
mod static_expression
Name Resolution Rules
5/5Each simple_expression
in a signed_integer_type_definition
is expected to be of any integer type; they can be of different integer types . The expression
in a modular_type_definition
is likewise expected to be of any integer type.
Legality Rules
6The simple_expression
s of a signed_integer_type_definition
shall be static, and their values shall be in the range System.Min_Int .. System.Max_Int.
The expression
of a modular_type_definition
shall be static, and its value (the modulus) shall be positive, and shall be no greater than System.Max_Binary_Modulus if a power of 2, or no greater than System.Max_Nonbinary_Modulus if not.
Static Semantics
8The set of values for a signed integer type is the (infinite) set of mathematical integers[, though only values of the base range of the type are fully supported for run-time operations]. The set of values for a modular integer type are the values from 0 to one less than the modulus, inclusive.
A signed_integer_type_definition
defines an integer type whose base range includes at least the values of the simple_expression
s and is symmetric about zero, excepting possibly an extra negative value. A signed_integer_type_definition
also defines a constrained first subtype of the type, with a range whose bounds are given by the values of the simple_expression
s, converted to the type being defined.
A modular_type_definition
defines a modular type whose base range is from zero to one less than the given modulus. A modular_type_definition
also defines a constrained first subtype of the type with a range that is the same as the base range of the type.
There is a predefined signed integer subtype named Integer[, declared in the visible part of package Standard]. It is constrained to the base range of its type.
Integer has two predefined subtypes, [declared in the visible part of package Standard:]
subtype Natural is Integer range 0 .. Integer'Last;
subtype Positive is Integer range 1 .. Integer'Last;
A type defined by an integer_type_definition
is implicitly derived from root_integer, an anonymous predefined (specific) integer type, whose base range is System.Min_Int .. System.Max_Int. However, the base range of the new type is not inherited from root_integer, but is instead determined by the range or modulus specified by the integer_type_definition
. [Integer literals are all of the type universal_integer, the universal type (see 3.4.1) for the class rooted at root_integer, allowing their use with the operations of any integer type.]
derived_type_definition
. In particular, integer types defined via a derived_type_definition
inherit their base range from their parent type. A type defined by an integer_type_definition
does not necessarily inherit its base range from root_integer. It is not specified whether the implicit derivation from root_integer is direct or indirect, not that it really matters. All we want is for all integer types to be descendants of root_integer.derived_type_definition
(see 3.4), or a private_extension_declaration
(see 7.3, 7.3.1, and 12.5.1). The position number of an integer value is equal to the value.
For every modular subtype S, the following attributes are defined:
S'Mod
- S'Mod denotes a function with the following specification:
function S'Mod (Arg : universal_integer)
return S'Base
- This function returns Arg mod S'Modulus, as a value of the type of S.
S'Modulus- S'Modulus yields the modulus of the type of S, as a value of the type universal_integer.
Dynamic Semantics
18The elaboration of an integer_type_definition
creates the integer type and its first subtype.
For a modular type, if the result of the execution of a predefined operator (see 4.5) is outside the base range of the type, the result is reduced modulo the modulus of the type to a value that is within the base range of the type.
For a signed integer type, the exception Constraint_Error is raised by the execution of an operation that cannot deliver the correct result because it is outside the base range of the type. [ For any integer type, Constraint_Error is raised by the operators "/", "rem", and "mod" if the right operand is zero.]
Implementation Requirements
21In an implementation, the range of Integer shall include the range –2**15+1 .. +2**15–1.
If Long_Integer is predefined for an implementation, then its range shall include the range –2**31+1 .. +2**31–1.
System.Max_Binary_Modulus shall be at least 2**16.
Implementation Permissions
24/5For the execution of a predefined operation of a signed integer type, it is optional to raise Constraint_Error if the result is outside the base range of the type, so long as the correct result is produced.
An implementation may provide additional predefined signed integer types[, declared in the visible part of Standard], whose first subtypes have names of the form Short_Integer, Long_Integer, Short_Short_Integer, Long_Long_Integer, etc. Different predefined integer types are allowed to have the same base range. However, the range of Integer should be no wider than that of Long_Integer. Similarly, the range of Short_Integer (if provided) should be no wider than Integer. Corresponding recommendations apply to any other predefined integer types. An implementation may support base ranges for which there is no corresponding named integer type . The range of each first subtype should be the base range of its type.
An implementation may provide nonstandard integer types, descendants of root_integer that are declared outside of the specification of package Standard, which may have different characteristics than a type defined by an integer_type_definition
. For example, a nonstandard integer type can have an asymmetric base range or it can be disallowed as an array or loop index (a very long integer). Any type descended from a nonstandard integer type is also nonstandard. An implementation may place arbitrary restrictions on the use of such types; it is implementation defined whether operators that are predefined for “any integer type” are defined for a particular nonstandard integer type. [In any case, such types are not permitted as explicit_generic_actual_parameter
s for formal scalar types — see 12.5.2.]
For a one's complement machine, the high bound of the base range of a modular type whose modulus is one less than a power of 2 may be equal to the modulus, rather than one less than the modulus. It is implementation defined for which powers of 2, if any, this permission is exercised.
{8652/0003} For a one's complement machine, implementations may support nonbinary modulus values greater than System.Max_Nonbinary_Modulus. It is implementation defined which specific values greater than System.Max_Nonbinary_Modulus, if any, are supported.
Implementation Advice
28An implementation should support Long_Integer in addition to Integer if the target machine supports 32-bit (or longer) arithmetic. No other named integer subtypes are recommended for package Standard. Instead, appropriate named integer subtypes should be provided in the library package Interfaces (see B.2).
An implementation for a two's complement machine should support modular types with a binary modulus up to System.Max_Int*2+2. An implementation should support a nonbinary modulus up to Integer'Last.
signed_integer_type_definition
(see 4.5, “Operators and Expression Evaluation”). For modular types, these same operators are predefined, plus bit-wise logical operators (and, or, xor, and not). In addition, for the unsigned types declared in the language-defined package Interfaces (see B.2), functions are defined that provide bit-wise shifting and rotating.generic_formal_parameter_declaration
of the form "type T is mod <>;"; signed integer types match "type T is range <>;" (see 12.5.2). Examples
33Examples of integer types and subtypes:
type Page_Num is range 1 .. 2_000;
type Line_Size is range 1 .. Max_Line_Size;
35subtype Small_Int is Integer range -10 .. 10;
subtype Column_Ptr is Line_Size range 1 .. 10;
subtype Buffer_Size is Integer range 0 .. Max;
36type Byte is mod 256; -- an unsigned byte
type Hash_Index is mod 97; -- modulus is prime
Extensions to Ada 83
Wording Changes from Ada 83
Extensions to Ada 95
Wording Changes from Ada 95
3.5.5 Operations of Discrete Types
Static Semantics
1For every discrete subtype S, the following attributes are defined:
S'Pos
- S'Pos denotes a function with the following specification:
function S'Pos(Arg : S'Base)
return universal_integer
- This function returns the position number of the value of Arg, as a value of type universal_integer.
S'Val- S'Val denotes a function with the following specification:
function S'Val(Arg : universal_integer)
return S'Base
- This function returns a value of the type of S whose position number equals the value of Arg. For the evaluation of a call on S'Val, if there is no value in the base range of its type with the given position number, Constraint_Error is raised.
For every static discrete subtype S for which there exists at least one value belonging to S that satisfies the predicates of S, the following attributes are defined:
S'First_Valid
- S'First_Valid denotes the smallest value that belongs to S and satisfies the predicates of S. The value of this attribute is of the type of S.
S'Last_Valid- S'Last_Valid denotes the largest value that belongs to S and satisfies the predicates of S. The value of this attribute is of the type of S.
[First_Valid and Last_Valid attribute_reference
s are always static expressions. Any explicit predicate of S can only have been specified by a Static_Predicate aspect.]
attribute_reference
is static if the prefix is a static subtype (see 4.9), (true by definition) and any arguments are static (there are none). Similarly, a dynamic predicate always makes a subtype nonstatic. QED. Implementation Advice
8For the evaluation of a call on S'Pos for an enumeration subtype, if the value of the operand does not correspond to the internal code for any enumeration literal of its type [(perhaps due to an uninitialized variable)], then the implementation should raise Program_Error. This is particularly important for enumeration types with noncontiguous internal codes specified by an enumeration_representation_clause
.
S'Val(S'Pos(X)) = X
S'Pos(S'Val(N)) = N
Examples
14Examples of attributes of discrete subtypes:
-- For the types and subtypes declared in subclause 3.5.1 the following hold:
16-- Color'First = White, Color'Last = Black
-- Rainbow'First = Red, Rainbow'Last = Blue
17-- Color'Succ(Blue) = Rainbow'Succ(Blue) = Brown
-- Color'Pos(Blue) = Rainbow'Pos(Blue) = 4
-- Color'Val(0) = Rainbow'Val(0) = White
Extensions to Ada 83
Extensions to Ada 2005
Wording Changes from Ada 2012
3.5.6 Real Types
1Real types provide approximations to the real numbers, with relative bounds on errors for floating point types, and with absolute bounds for fixed point types.
Syntax
2real_type_definition
::=
floating_point_definition
| fixed_point_definition
Static Semantics
3A type defined by a real_type_definition
is implicitly derived from root_real, an anonymous predefined (specific) real type. [Hence, all real types, whether floating point or fixed point, are in the derivation class rooted at root_real.]
derived_type_definition
(see 3.4), or a private_extension_declaration
(see 7.3, 7.3.1, and 12.5.1).[ Real literals are all of the type universal_real, the universal type (see 3.4.1) for the class rooted at root_real, allowing their use with the operations of any real type. Certain multiplying operators have a result type of universal_fixed (see 4.5.5), the universal type for the class of fixed point types, allowing the result of the multiplication or division to be used where any specific fixed point type is expected.]
Dynamic Semantics
5The elaboration of a real_type_definition
consists of the elaboration of the floating_point_definition
or the fixed_point_definition
.
Implementation Requirements
6An implementation shall perform the run-time evaluation of a use of a predefined operator of root_real with an accuracy at least as great as that of any floating point type definable by a floating_point_definition
.
floating_point_definition
, and its safe range includes that of any such floating point type with the same Digits attribute. On some machines, there might be real types with less accuracy but a wider range, and hence run-time calculations with root_real might not be able to accommodate all values that can be represented at run time in such floating point or fixed point types. Implementation Permissions
7/5[For the execution of a predefined operation of a real type, it is optional to raise Constraint_Error if the result is outside the base range of the type, so long as the correct result is produced, or the Machine_Overflows attribute of the type is False (see G.2.1 ).]
An implementation may provide nonstandard real types, descendants of root_real that are declared outside of the specification of package Standard, which may have different characteristics than a type defined by a real_type_definition
. For example, a nonstandard real type can have an asymmetric or unsigned base range, or its predefined operations can wrap around or “saturate” rather than overflow (modular or saturating arithmetic), or it can have a different accuracy model than is standard (see G.2.1 ). Any type descended from a nonstandard real type is also nonstandard. An implementation may place arbitrary restrictions on the use of such types; it is implementation defined whether operators that are predefined for “any real type” are defined for a particular nonstandard real type. [In any case, such types are not permitted as explicit_generic_actual_parameter
s for formal scalar types — see 12.5.2.]
Wording Changes from Ada 83
real_type_definition
is modified to use the new syntactic categories floating_point_definition
and fixed_point_definition
, instead of floating_point_constraint
and fixed_point_constraint
, because the semantics of a type definition are significantly different than the semantics of a constraint.3.5.7 Floating Point Types
1For floating point types, the error bound is specified as a relative precision by giving the required minimum number of significant decimal digits.
Syntax
2floating_point_definition
::=
digits static_expression
[real_range_specification
]
3real_range_specification
::=
range static_simple_expression
.. static_simple_expression
Name Resolution Rules
4The requested decimal precision, which is the minimum number of significant decimal digits required for the floating point type, is specified by the value of the expression
given after the reserved word digits. This expression
is expected to be of any integer type.
Each simple_expression
of a real_range_specification
is expected to be of any real type[; the types can be different ].
Legality Rules
6The requested decimal precision shall be specified by a static expression
whose value is positive and no greater than System.Max_Base_Digits. Each simple_expression
of a real_range_specification
shall also be static. If the real_range_specification
is omitted, the requested decimal precision shall be no greater than System.Max_Digits.
real_range_specification
, for upward compatibility. These might not be the same if root_real has a base range that does not include ± 10.0**(4*Max_Base_Digits). A floating_point_definition
is illegal if the implementation does not support a floating point type that satisfies the requested decimal precision and range.
Static Semantics
8The set of values for a floating point type is the (infinite) set of rational numbers. The machine numbers of a floating point type are the values of the type that can be represented exactly in every unconstrained variable of the type. The base range (see 3.5) of a floating point type is symmetric around zero, except that it can include some extra negative values in some implementations.
The base decimal precision of a floating point type is the number of decimal digits of precision representable in objects of the type. The safe range of a floating point type is that part of its base range for which the accuracy corresponding to the base decimal precision is preserved by all predefined operations.
A floating_point_definition
defines a floating point type whose base decimal precision is no less than the requested decimal precision. If a real_range_specification
is given, the safe range of the floating point type (and hence, also its base range) includes at least the values of the simple expressions given in the real_range_specification
. If a real_range_specification
is not given, the safe (and base) range of the type includes at least the values of the range –10.0**(4*D) .. +10.0**(4*D) where D is the requested decimal precision. [The safe range can include other values as well. The attributes Safe_First and Safe_Last give the actual bounds of the safe range.]
A floating_point_definition
also defines a first subtype of the type. If a real_range_specification
is given, then the subtype is constrained to a range whose bounds are given by a conversion of the values of the simple_expression
s of the real_range_specification
to the type being defined. Otherwise, the subtype is unconstrained.
There is a predefined, unconstrained, floating point subtype named Float[, declared in the visible part of package Standard].
Dynamic Semantics
13[The elaboration of a floating_point_definition
creates the floating point type and its first subtype.]
Implementation Requirements
14In an implementation that supports floating point types with 6 or more digits of precision, the requested decimal precision for Float shall be at least 6.
If Long_Float is predefined for an implementation, then its requested decimal precision shall be at least 11.
Implementation Permissions
16/5An implementation is allowed to provide additional predefined floating point types[, declared in the visible part of Standard], whose (unconstrained) first subtypes have names of the form Short_Float, Long_Float, Short_Short_Float, Long_Long_Float, etc. Different predefined floating point types are allowed to have the same base decimal precision. However, the precision of Float should be no greater than that of Long_Float. Similarly, the precision of Short_Float (if provided) should be no greater than Float. Corresponding recommendations apply to any other predefined floating point types. An implementation may support base decimal precisions for which there is no corresponding named floating point type .
Implementation Advice
17An implementation should support Long_Float in addition to Float if the target machine supports 11 or more digits of precision. No other named floating point subtypes are recommended for package Standard. Instead, appropriate named floating point subtypes should be provided in the library package Interfaces (see B.2).
Examples
19Examples of floating point types and subtypes:
type Coefficient is digits 10 range -1.0 .. 1.0;
21type Real is digits 8;
type Mass is digits 7 range 0.0 .. 1.0E35;
22subtype Probability is Real range 0.0 .. 1.0; -- a subtype with a smaller range
Inconsistencies With Ada 83
Wording Changes from Ada 83
floating_point_constraint
and floating_accuracy_definition
are removed. The syntax rules for floating_point_definition
and real_range_specification
are new.digits_constraint
is given in 3.5.9, “Fixed Point Types”. In J.3 we indicate that a digits_constraint
may be applied to a floating point subtype_mark
as well (to be compatible with Ada 83's floating_point_constraint
).3.5.8 Operations of Floating Point Types
Static Semantics
1The following attribute is defined for every floating point subtype S:
S'Digits
- {8652/0004} S'Digits denotes the requested decimal precision for the subtype S. The value of this attribute is of the type universal_integer. The requested decimal precision of the base subtype of a floating point type T is defined to be the largest value of d for which
ceiling(d * log(10) / log(T'Machine_Radix)) + g <= T'Model_Mantissa
where g is 0 if Machine_Radix is a positive power of 10 and 1 otherwise.
Wording Changes from Ada 95
3.5.9 Fixed Point Types
1A 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.
Syntax
2fixed_point_definition
::=
ordinary_fixed_point_definition
| decimal_fixed_point_definition
3ordinary_fixed_point_definition
::=
delta static_expression
real_range_specification
4decimal_fixed_point_definition
::=
delta static_expression
digits static_expression
[real_range_specification
]
5/4digits_constraint
::=
digits static_simple_expression
[range_constraint
]
Name Resolution Rules
6For 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.
The simple_expression
of a digits_constraint
is expected to be of any integer type.
Legality Rules
7In a fixed_point_definition
or digits_constraint
, the expression
s given after the reserved words delta and digits shall be static; their values shall be positive.
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.
Static Semantics
12The 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 thereal_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 expression
s of the real_range_specification
. Otherwise, the range of the first subtype is –(10**digits–1)*delta .. +(10**digits–1)*delta.
Dynamic Semantics
17The 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 simple_expression
. A digits_constraint
is compatible with a decimal fixed point subtype if the value of the simple_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.
digits_constraint
is essentially equivalent to a range_constraint
.type D is delta 0.01 digits 7 range -0.00 .. 9999.99;
digits_constraint
"digits 6" specifies an implicit range of "–9999.99 .. 9999.99". Thus, "digits 6" is not compatible with the constraint of D, but "digits 6 range 0.00 .. 9999.99" is compatible.digits_constraint
s and delta_constraint
s 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”.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) simple_expression
given after the reserved word digits. If this check fails, Constraint_Error is raised.
Implementation Requirements
20The implementation shall support at least 24 bits of precision (including the sign bit) for fixed point types.
Implementation Permissions
21Implementations are permitted to support only smalls 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 smalls, and decimal fixed point type declarations with digits up to at least 18.
type Fraction is delta 2.0**(-15) range -1.0 .. 1.0;
Examples
25Examples of fixed point types and subtypes:
type Volt is delta 0.125 range 0.0 .. 255.0;
27-- 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
28type Money is delta 0.01 digits 15; -- decimal fixed point
subtype Salary is Money digits 10;
-- Money'Last = 10.0**13 – 0.01, Salary'Last = 10.0**8 – 0.01
Inconsistencies With Ada 83
Extensions to Ada 83
Wording Changes from Ada 83
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
). Wording Changes from Ada 95
Incompatibilities With Ada 2012
digits_constraint
is a simple_expression
. This is compatible with one very unlikely exception: if the digits expression is a static expression of a modular type using an unparenthesized logical operator (like and or or). Parenthesizing the expression will make it legal in that case. The change is necessary to eliminate syntax ambguities in derived_type_definition
s. Wording Changes from Ada 2012
digits_constraint
. This was missing since Ada 95, but as it is obvious and unchanged from Ada 83, we don't consider it an incompatibility. 3.5.10 Operations of Fixed Point Types
Static Semantics
1The following attributes are defined for every fixed point subtype S:
S'Small
- {8652/0005} S'Small denotes the small of the type of S. The value of this attribute is of the type universal_real. Small may be specified for nonderived ordinary fixed point types via an
attribute_definition_clause
(see 13.3); the expression of such a clause shall be static and positive.
S'Delta
- S'Delta denotes the delta of the fixed point subtype S. The value of this attribute is of the type universal_real.
delta_constraint
.S'Fore
- S'Fore yields the minimum number of characters needed before the decimal point for the decimal representation of any value of the subtype S, assuming that the representation does not include an exponent, but includes a one-character prefix that is either a minus sign or a space. (This minimum number does not include superfluous zeros or underlines, and is at least 2.) The value of this attribute is of the type universal_integer.
S'Aft- S'Aft yields the number of decimal digits needed after the decimal point to accommodate the delta of the subtype S, unless the delta of the subtype S is greater than 0.1, in which case the attribute yields the value one. [(S'Aft is the smallest positive integer N for which (10**N)*S'Delta is greater than or equal to one.)] The value of this attribute is of the type universal_integer.
The following additional attributes are defined for every decimal fixed point subtype S:
S'Digits
- S'Digits denotes the digits of the decimal fixed point subtype S, which corresponds to the number of decimal digits that are representable in objects of the subtype. The value of this attribute is of the type universal_integer. Its value is determined as follows:
- For a first subtype or a subtype defined by a
subtype_indication
with adigits_constraint
, the digits is the value of the expression given after the reserved word digits; 9/5 - For a subtype defined by a
subtype_indication
without adigits_constraint
, the digits of the subtype is the same as that of the subtype denoted by thesubtype_mark
in thesubtype_indication
;
- The digits of a base subtype is the largest integer D such that the range –(10**D–1)*delta .. +(10**D–1)*delta is included in the base range of the type.
S'Scale
- S'Scale denotes the scale of the subtype S, defined as the value N such that S'Delta = 10.0**(–N). [The scale indicates the position of the point relative to the rightmost significant digits of values of subtype S.] The value of this attribute is of the type universal_integer.
S'Round
- S'Round denotes a function with the following specification:
function S'Round(X : universal_real)
return S'Base
- The function returns the value obtained by rounding X (away from 0, if X is midway between two values of the type of S).
delta_constraint
s (see J.3).