Pre-defined integer types
These integer types are pre-defined:
int
the generic signed integer type; its size is platform dependent and has the same size as a pointer. This type should be used in general. An integer literal that has no type suffix is of this type if it is in the range low(int32)..high(int32) otherwise the literal’s type is int64.
intXX
additional signed integer types of XX bits use this naming scheme (example: int16 is a 16 bit wide integer). The current implementation supports int8, int16, int32, int64. Literals of these types have the suffix ‘iXX.
uint
the generic unsigned integer type; its size is platform dependent and has the same size as a pointer. An integer literal with the type suffix ‘u is of this type.
uintXX
additional unsigned integer types of XX bits use this naming scheme (example: uint16 is a 16 bit wide unsigned integer). The current implementation supports uint8, uint16, uint32, uint64. Literals of these types have the suffix ‘uXX. Unsigned operations all wrap around; they cannot lead to over- or underflow errors.
In addition to the usual arithmetic operators for signed and unsigned integers (+ - * etc.) there are also operators that formally work on signed integers but treat their arguments as unsigned: They are mostly provided for backwards compatibility with older versions of the language that lacked unsigned integer types. These unsigned operations for signed integers use the % suffix as convention:
operation | meaning |
---|---|
a +% b | unsigned integer addition |
a -% b | unsigned integer subtraction |
a *% b | unsigned integer multiplication |
a /% b | unsigned integer division |
a %% b | unsigned integer modulo operation |
a <% b | treat a and b as unsigned and compare |
a <=% b | treat a and b as unsigned and compare |
ze(a) | extends the bits of a with zeros until it has the width of the int type |
toU8(a) | treats a as unsigned and converts it to an unsigned integer of 8 bits (but still the int8 type) |
toU16(a) | treats a as unsigned and converts it to an unsigned integer of 16 bits (but still the int16 type) |
toU32(a) | treats a as unsigned and converts it to an unsigned integer of 32 bits (but still the int32 type) |
Automatic type conversion is performed in expressions where different kinds of integer types are used: the smaller type is converted to the larger.
A narrowing type conversion converts a larger to a smaller type (for example int32 -> int16. A widening type conversion converts a smaller type to a larger type (for example int16 -> int32). In Nim only widening type conversions are implicit:
var myInt16 = 5i16
var myInt: int
myInt16 + 34 # of type ``int16``
myInt16 + myInt # of type ``int``
myInt16 + 2i32 # of type ``int32``
However, int literals are implicitly convertible to a smaller integer type if the literal’s value fits this smaller type and such a conversion is less expensive than other implicit conversions, so myInt16 + 34 produces an int16 result.
For further details, see Convertible relation.