## Description

Unsigned integers in Ada have a value range from 0 to some positive number (not necessarily 1 subtracted from some power of 2). They are defined using the `mod` keyword because they implement a wrap-around arithmetic.

``` `mod` Modulus
```

where 'First is 0 and 'Last is Modulus - 1.

Wrap-around arithmetic means that 'Last + 1 = 0 = 'First, and 'First - 1 = 'Last. Additionally to the normal arithmetic operators, bitwise `and`, `or` and `xor` are defined for the type (see below).

The predefined package Interfaces (RM B.2 (Annotated)) presents unsigned integers based on powers of 2

````type` Unsigned_n `is` `mod` 2**n;
```

for which also shift and rotate operations are defined. The values of n depend on compiler and target architecture.

You can use `range` to sub-range a modular type:

````type` Byte `is` `mod` 256;
`subtype` Half_Byte `is` Byte `range` 0 .. 127;
```

But beware: the Modulus of Half_Byte is still 256! Arithmetic with such a type is interesting to say the least.

## Bitwise Operations

Be very careful with bitwise operators `and`, `or`, `xor`, `not`, when the modulus is not a power of two. An example might exemplify the problem.

````type` Unsigned `is` `mod` 2**5;   -- modulus 32
X: Unsigned := 2#10110#;     -- 22
`not` X        = 2#01001#      -- bit reversal: 9 ( = 31 - 22 ) as expected
```

The other operators work similarly.

Now take a modulus that is not a power of two. Naive expectations about the results may lead out of the value range. As an example take again the `not` operator (see the RM for the others):

````type` Unsigned `is` `mod` 5;
X: Unsigned := 2#001#;  -- 1, bit reversal: 2#110# = 6 leads out of range
```

The definition of `not` is therefore:

``` `not` X = Unsigned'Last – X  -- here: 4 – 1 = 2#011#
```