# Ada Programming/Types/mod

## Description[edit | edit source]

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[edit | edit source]

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#

## See also[edit | edit source]

### Wikibook[edit | edit source]

### Ada Reference Manual[edit | edit source]

- 4.4: Expressions
^{[Annotated]} - 3.5.4: Integer Types
^{[Annotated]}