3.5.4 Integer Types
An 
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
Name Resolution Rules
Legality Rules
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
The 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 
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. 
 
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
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
In 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
For the execution of a predefined operation of a 
signed integer type, the implementation need not 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. There need not be a named integer 
type corresponding to each distinct base range supported by an implementation. 
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 
need not have all the standard characteristics of a type defined by an 
integer_type_definition. 
For example, a nonstandard integer type might have an asymmetric base 
range or it might not be allowed 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_parameters 
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.
 
   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
An 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. 
 
33  
Integer 
literals are of the anonymous predefined integer type 
universal_integer. 
Other integer types have no literals. However, the overload resolution 
rules (see 
8.6, “
The 
Context of Overload Resolution”) allow expressions of the type 
universal_integer whenever an integer type is expected.
 
34  The same arithmetic operators are predefined 
for all signed integer types defined by a 
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.
 
Examples
Examples of integer 
types and subtypes: 
type Page_Num  is range 1 .. 2_000;
type Line_Size is range 1 .. Max_Line_Size;
subtype Small_Int   is Integer   range -10 .. 10;
subtype Column_Ptr  is Line_Size range 1 .. 10;
subtype Buffer_Size is Integer   range 0 .. Max;
type Byte        is mod 256; -- an unsigned byte
type Hash_Index  is mod 97;  -- modulus is prime
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe