# Gem #26: The Mod Attribute

### Let's get started…

Ada has two kinds of integer type: signed and modular:

typeSigned_Integerisrange1..1_000_000;typeModularismod2**32;

Operations on signed integers can overflow: if the result is outside the base range, `Constraint_Error`

will be raised. The base range of `Signed_Integer`

is the range of `Signed_Integer'Base`

, which is chosen by the compiler, but is likely to be something like `-2**31..2**31-1`

.

Operations on modular integers use modular (wraparound) arithmetic.

For example:

X : Modular := 1; X := - X;

Negating X gives -1, which wraps around to `2**32-1`

, i.e. all-one-bits.

But what about a type conversion from signed to modular? Is that a signed operation (so it should overflow) or is it a modular operation (so it should wrap around)? The answer in Ada is the former -- that is, if you try to convert, say, `Integer'(-1)`

to Modular, you will get `Constraint_Error`

:

I : Integer := -1; X := Modular (I);-- raises Constraint_Error

In Ada 95, the only way to do that conversion is to use `Unchecked_Conversion`

, which is somewhat uncomfortable. Furthermore, if you're trying to convert to a generic formal modular type, how do you know what size of signed integer type to use? Note that `Unchecked_Conversion`

might malfunction if the source and target types are of different sizes.

A small feature added to Ada 2005 solves the problem: the `Mod`

attribute:

generictypeFormal_Modularismod<>;packageMod_AttributeisfunctionFreturnFormal_Modular;endMod_Attribute;packagebodyMod_AttributeisA_Signed_Integer : Integer := -1;functionFreturnFormal_ModularisbeginreturnFormal_Modular'Mod (A_Signed_Integer);endF;endMod_Attribute;

The `Mod`

attribute will correctly convert from any integer type to a given modular type, using wraparound semantics. Thus, F will return the all-ones bit pattern, for whatever modular type is passed to `Formal_Modular`

.

### Related Source Code

Ada Gems example files are distributed by AdaCore and may be used or modified for any purpose without restrictions.

#### Attached Files

- gem_26.ada - (4 KB)