Itegers are used to represent numerical information, where only whole numbers are accurate enough. That means, it is good wherever is need to describe quantities, no matter if they are positive, negative or zero. Unlike integers in standard programming languages, there is no upper nor lower bound for ASN.1 integer type.
The basic notation of this type is simply the keyword INTEGER.
WholeNumber ::= INTEGER
Of course, it can be optionaly tweaked by some modificators. One of them is collection of identifiers, where each value is coupled with identifier:
BingoNumbers ::= INTEGER {
kellysEye(1), meAndYou(2), youAndMe(3), knockAtTheDoor(4),
...
clicketyClick(66), twoFatLadies(88),
topOfTheHouse(100)
}
Assigning identifiers this way can be seen as definig a new integer-like type enriched with distinguished values. As you can see in this example, the numbers corresponding to identifiers need not to form a contignuous range of integers, nor appear in particilar order (although it is usually better if they do). On the other hand, particular identifier can appear only once in this set and the same is for numbers and although only limited number of integers is assigned a distinct identifier, this way defined type still contains all the integers. If this is undesired, use some subtyping. Using this notation still alows using standard numerical values which can be replaced by appropriate identifiers where assigned.
Lots of early examples of ASN.1 use frequently this asignment for identifying the members of some small finite set of non-numerical possibilities, which is in current version replaced by ENUMERATED type, unless specifically needed (as in our previous example).
Another way to enhance integers is subtyping. There are several constructions including single values and contained subtypes, which are valid for all types, but also value ranges, because integers are ordered. Thus we should define BingoNumbers as
BingoNumbers ::= INTEGER {
...
} (1 .. 100)
or even:
BingoNumbers ::= INTEGER {
...
} (kellysEye .. topOfTheHouse)
which is probably more intuitive.
When using ranges, there are special keywords to exclude lower/upper bound and use the maximal available range. The type PositiveInteger uses both of them: < to exclude zero and MAX as an upper bound.
PositiveInteger ::= INTEGER (0<..MAX)
This way you can e.g. define type of LongInt that uses a maximum of 4-byte capacity:
LongInt ::= INTEGER (-2147483648 .. 2147483647)
and then use LongInt instead of INTEGER.
To complete this section, here are some more examples of subtyping INTEGER:
Temperature ::= INTEGER (-100 .. 60)
NegativeInteger ::= INTEGER (MIN .. <0)
Zero ::= INTEGER (0)
NonZero ::= INTEGER (INCLUDES NegativeInteger | INCLUDES PositiveInteger)
MyBingoNumbers ::= BingoNumbers
(kellysEye | knockAtTheDoor | 25 | twoFatLadies | 93)