The Basis library allows for multiple modules for signed integers of different sizes. These all satisfy the common signature INTEGER. On 32 bit architectures SML/NJ only supplies 31 and 32 bit signed integers.
The 31 bit size looks strange but it is designed to help the garbage collector (GC). The GC needs to scan each word in the heap and tell whether it is a pointer or not. The SML/NJ solution is to use the least significant bit (LSB) to tell the difference. If you want a 32 bit integer then it must be allocated in a separate heap record with a type tag. (See the section called Heap Object Layout in Chapter 7 for details). You should use 31 bit integers wherever possible for more efficient storage.
The structures Int and Int31 are both 31 bit integers and the top-level type int is the same as Int.int. Use the Int32 structure for 32 bit integers. There is also a structure called LargeInt which is supposed to be the largest integer type that the hardware implements. It is used as an intermediary when converting between integers of other sizes. The bind-largest.sml file in the compiler's boot directory shows the definitions of the various integer types in terms of sizes. (The Position type is used for file positions in the Posix functions).
To get an integer literal of a type other than Int.int you will need a type constraint e.g. write (23: Int32.int) to get the 32 bit integer value 23. You can use a 0x prefix for hexadecimal, like in C.
All integer operations check for overflow, unlike C. The Overflow exception is raised if there is any integer overflow or underflow.
There are also matching unsigned integer structures, Word, Word8, Word31, Word32, LargeWord and SysWord. These are of sizes 8, 31 and 32 bits as you would expect. Use a 0w prefix for word values and 0wx for word values in hexadecimal. Arithmetic on unsigned integers does not raise the Overflow exception.
The unsigned integer structures conform to the WORD signature which adds bit-wise operations to the usual integer operations.
Finally there is an infinite precision integer structure IntInf. This represents numbers with any number of digits. To input a literal IntInf.int value you need to use fromString i.e. write
valOf(IntInf.fromString "123456789876543210000000000") |
Words can be serialised into byte arrays using the PACK_WORD structures. These implement 16 and 32 bit serialisation in big or little endian order in the Pack16Big, Pack32Big, Pack16Little and Pack32Little structures.