The Standard ML Basis Library


The INTEGER signature

Instances of the signature INTEGER provide a type of signed integers of either a fixed or arbitrary precision, and arithmetic and conversion operations. For fixed precision implementations, most arithmetic operations raise the exception Overflow when their result is not representable.

Fixed precision representations are required to be 2's complement. Implementations of arbitrary precision should appear as 2's complement under conversion to and from words.


Synopsis

signature INTEGER
structure Int : INTEGER
structure Int8 : INTEGER
structure FixedInt : INTEGER
structure LargeInt : INTEGER
structure Int{N} : INTEGER
structure Position : INTEGER

Interface

eqtype int
val toLarge : int -> LargeInt.int
val fromLarge : LargeInt.int -> int
val toInt : int -> Int.int
val fromInt : Int.int -> int
val precision : Int.int option
val minInt : int option
val maxInt : int option
val ~ : int -> int
val * : (int * int) -> int
val div : (int * int) -> int
val mod : (int * int) -> int
val quot : (int * int) -> int
val rem : (int * int) -> int
val + : (int * int) -> int
val - : (int * int) -> int
val compare : (int * int) -> order
val > : (int * int) -> bool
val >= : (int * int) -> bool
val < : (int * int) -> bool
val <= : (int * int) -> bool
val abs : int -> int
val min : (int * int) -> int
val max : (int * int) -> int
val sign : int -> Int.int
val sameSign : (int * int) -> bool
val fmt : StringCvt.radix -> int -> string
val toString : int -> string
val fromString : string -> int option
val scan : StringCvt.radix -> (char, 'a) StringCvt.reader -> 'a -> (int * 'a) option

Description

eqtype int

toLarge i
converts i to the equivalent integer value of type LargeInt.int.

fromLarge i
converts i to the equivalent integer value of type int, raising Overflow if the value doesn't fit.

toInt i
converts i to the equivalent value in the default integer type. Raises Overflow if the value doesn't fit.

fromInt i
converts i to the equivalent integer value of type int, raising Overflow if the value doesn't fit.

precision
if SOME n, denotes the number n of significant bits in type int, including the sign bit. If it is NONE, int has arbitrary precision. The precision need not necessarily be a power of two.

minInt
maxInt
denote the minimal (most negative) and the maximal (most positive) integers, respectively, representable by int. If a value is NONE, int can represent all negative (respectively, positive) integers, within the limits of heap size.

If precision is SOME n, then we have minInt = -2(n-1) and maxInt = 2(n-1) - 1.

~ i
returns the negation of i, i.e., (0 - i). Raises Overflow when the result is not representable. This can happen, for example, when int is an n-bit two's-complement integer type, and ~ is applied to -2 (n-1).

i * j
returns the product of i and j. Raises Overflow when the result is not representable.

i div j
returns the truncated quotient of the division of i by j, i.e., floor (i / j). Raises Overflow when the result is not representable, or Div when j = 0. Note that rounding is towards negative infinity, not zero.

i mod j
returns the remainder of the division of i by j. Raises Div when j = 0. (i mod j) has the same sign as j, and it holds that
          (i div j) * j + (i mod j) = i
	  


quot (i, j)
returns the truncated quotient of the division of i by j, i.e., trunc (i / j). Raises Overflow when the result is not representable, or Div when j = 0. Note that unlike div, quot rounds towards zero. In addition, unlike div and mod, neither quot nor rem are infix by default; an appropriate infix declaration would be infix 7 quot rem.
Implementation note:

This is the semantics of most hardware divide instructions, so quot may be faster than div.



i rem j
returns the remainder of the division of i by j. Raises Div when j = 0. (i rem j) has the same sign as i, and it holds that
          (i quot j) * j + (i rem j) = i
	  
This is the semantics of most hardware divide instructions, so rem may be faster than mod.

i + j
returns the sum of i and j. Raises Overflow when the result is not representable.

i - j
returns the difference of i and j. Raises Overflow when the result is not representable.

compare (i, j)
returns LESS, EQUAL, or GREATER when i is less than, equal to, or greater than j, respectively.

i > j
i >= j
i < j
i <= j
return true if the corresponding relation holds between the two integers.

abs i
returns the absolute value (magnitude) of i. Raises Overflow when the result is not representable.

min (i, j)
max (i, j)
returns the smaller (respectively, larger) of i and j.

sign i
returns ~1, 0 or 1 when i is less than, equal to, or greater than 0, respectively.

sameSign (i, j)
is equivalent to (sign i = sign j).

fmt radix i
returns a string containing a representation of i formatted according to radix, with ~ used as the sign for negative numbers. The hexadecimal digits 10-15 are represented as [A-F]. No prefix "0x" is generated for the hexadecimal representation.

toString i
returns a signed decimal representation of i. It is equivalent to fmt StringCvt.DEC i.

fromString s
returns SOME i if a number i in the format [+~-]?[0-9]+ can be parsed from a prefix of string s, ignoring initial whitespace; NONE is returned otherwise. Raises Overflow when an integer can be parsed, but is too large to fit in type int. Equivalent to StringCvt.scanString (scan StringCvt.DEC).

scan radix getc src
returns SOME (i,r) if an integer in the format denoted by radix can be parsed from a prefix of the character source src after skipping whitespace; i is the value of the integer parsed, r is the rest of the character source. NONE is returned otherwise. Raises Overflow when an integer can be parsed, but is too large to fit in type int. The type of scan can also be written as
StringCvt.radix -> (char, 'a) StringCvt.reader -> (int, 'a) StringCvt.reader
          

The format expected depends on radix. Regular expressions for these formats are given below.


StringCvt.BIN [+~-]?[0-1]+
StringCvt.OCT [+~-]?[0-7]+
StringCvt.DEC [+~-]?[0-9]+
StringCvt.HEX [+~-]?(Ox|0X)?[0-9a-fA-F]+

Note that strings such as "0xg" and "0x 123" are scanned as SOME 0, even using a hexadecimal radix.


Discussion

Implementation note:

It is recommended that compilers recognize the idiom of converting between integers of differing precisions using an intermediate representation (e.g., Int31.fromLarge o Int8.toLarge) and optimize these compositions.

The type FixedInt.int is the largest fixed precision integer supported, while the type LargeInt.int is the largest integer supported. If an implementation provides the IntInf structure, then the type LargeInt.intis be the same as IntInf.int. The type Position.int is used to represent positions in files and I/O streams.

See Also

IntInf, StringCvt