Chapter 21 | The num library: arbitrary-precision rational arithmetic

The `num` library implements integer arithmetic and rational arithmetic in arbitrary precision.
More documentation on the functions provided in this library can be found in The CAML Numbers Reference Manual by Valérie Ménissier-Morain, technical report 141, INRIA, july 1992 (available electronically, `ftp://ftp.inria.fr/INRIA/publication/RT/RT-0141.ps.gz`).
Programs that use the `num` library must be linked as follows:

            ocamlc other options nums.cma other files
            ocamlopt other options nums.cmxa other files

For interactive use of the `nums` library, do:

            ocamlmktop -o mytop nums.cma
            ./mytop

or (if dynamic linking of C libraries is supported on your platform), start `ocaml` and type `#load "nums.cma";;`.

21.1 | Module `Num`: operation on arbitrary-precision numbers

    open Nat
    open Big_int
    open Ratio

> Numbers (type `num`) are arbitrary-precision rational numbers, plus the special elements `1/0` (infinity) and `0/0` (undefined).

    type num = Int of int | Big_int of big_int | Ratio of ratio

> The type of numbers.

Arithmetic operations

    val (+/) : num -> num -> num
    val add_num : num -> num -> num

> Addition

    val minus_num : num -> num

> Unary negation.

    val (-/) : num -> num -> num
    val sub_num : num -> num -> num

> Subtraction

    val (*/) : num -> num -> num
    val mult_num : num -> num -> num

> Multiplication

    val square_num : num -> num

> Squaring

    val (//) : num -> num -> num
    val div_num : num -> num -> num

> Division

    val quo_num : num -> num -> num
    val mod_num : num -> num -> num

> Euclidean division: quotient and remainder

    val (**/) : num -> num -> num
    val power_num : num -> num -> num

> Exponentiation

    val is_integer_num : num -> bool

> Test if a number is an integer

    val integer_num : num -> num
    val floor_num : num -> num
    val round_num : num -> num
    val ceiling_num : num -> num

> Approximate a number by an integer. `floor_num n` returns the largest integer smaller or equal to `n`. `ceiling_num n` returns the smallest integer bigger or equal to `n`. `integer_num n` returns the integer closest to `n`. In case of ties, rounds towards zero. `round_num n` returns the integer closest to `n`. In case of ties, rounds off zero.

    val sign_num : num -> int

> Return `-1`, `0` or `1` according to the sign of the argument.

    val (=/) : num -> num -> bool
    val (</) : num -> num -> bool
    val (>/) : num -> num -> bool
    val (<=/) : num -> num -> bool
    val (>=/) : num -> num -> bool
    val (<>/) : num -> num -> bool
    val eq_num : num -> num -> bool
    val lt_num : num -> num -> bool
    val le_num : num -> num -> bool
    val gt_num : num -> num -> bool
    val ge_num : num -> num -> bool

> Usual comparisons between numbers

    val compare_num : num -> num -> int

> Return `-1`, `0` or `1` if the first argument is less than, equal to, or greater than the second argument.

    val max_num : num -> num -> num
    val min_num : num -> num -> num

> Return the greater (resp. the smaller) of the two arguments.

    val abs_num : num -> num

> Absolute value.

    val succ_num: num -> num

> `succ n` is `n+1`

    val pred_num: num -> num

> `pred n` is `n-1`

    val incr_num: num ref -> unit

> `incr r` is `r:=!r+1`, where `r` is a reference to a number.

    val decr_num: num ref -> unit

> `decr r` is `r:=!r-1`, where `r` is a reference to a number.

Coercions with strings

    val string_of_num : num -> string

> Convert a number to a string, using fractional notation.

    val approx_num_fix : int -> num -> string
    val approx_num_exp : int -> num -> string

> Approximate a number by a decimal. The first argument is the required precision. The second argument is the number to approximate. `approx_fix` uses decimal notation; the first argument is the number of digits after the decimal point. `approx_exp` uses scientific (exponential) notation; the first argument is the number of digits in the mantissa.

    val num_of_string : string -> num

> Convert a string to a number.

Coercions between numerical types

    val int_of_num : num -> int
    val num_of_int : int -> num
    val nat_of_num : num -> nat
    val num_of_nat : nat -> num
    val num_of_big_int : big_int -> num
    val big_int_of_num : num -> big_int
    val ratio_of_num : num -> ratio
    val num_of_ratio : ratio -> num
    val float_of_num : num -> float

21.2 | Module `Big_int`: operations on arbitrary-precision integers

> Big integers (type `big_int`) are signed integers of arbitrary size.

    open Nat
    type big_int

> The type of big integers.

    val zero_big_int : big_int

> The big integer `0`.

    val unit_big_int : big_int

> The big integer `1`.

Arithmetic operations

    val minus_big_int : big_int -> big_int

> Unary negation.

    val abs_big_int : big_int -> big_int

> Absolute value.

    val add_big_int : big_int -> big_int -> big_int

> Addition.

    val succ_big_int : big_int -> big_int

> Successor (add 1).

    val add_int_big_int : int -> big_int -> big_int

> Addition of a small integer to a big integer.

    val sub_big_int : big_int -> big_int -> big_int

> Subtraction.

    val pred_big_int : big_int -> big_int

> Predecessor (subtract 1).

    val mult_big_int : big_int -> big_int -> big_int

> Multiplication of two big integers.

    val mult_int_big_int : int -> big_int -> big_int

> Multiplication of a big integer by a small integer

    val square_big_int: big_int -> big_int

> Return the square of the given big integer

    val sqrt_big_int: big_int -> big_int

> `sqrt_big_int a` returns the integer square root of `a`, that is, the largest big integer `r` such that `r * r <= a`. Raise `Invalid_argument` if `a` is negative.

    val quomod_big_int : big_int -> big_int -> big_int * big_int

> Euclidean division of two big integers. The first part of the result is the quotient, the second part is the remainder. Writing `(q,r) = quomod_big_int a b`, we have `a = q * b + r` and `0 <= r < |b|`. Raise `Division_by_zero` if the divisor is zero.

    val div_big_int : big_int -> big_int -> big_int

> Euclidean quotient of two big integers. This is the first result `q` of `quomod_big_int` (see above).

    val mod_big_int : big_int -> big_int -> big_int

> Euclidean modulus of two big integers. This is the second result `r` of `quomod_big_int` (see above).

    val gcd_big_int : big_int -> big_int -> big_int

> Greatest common divisor of two big integers.

    val power_int_positive_int: int -> int -> big_int
    val power_big_int_positive_int: big_int -> int -> big_int
    val power_int_positive_big_int: int -> big_int -> big_int
    val power_big_int_positive_big_int: big_int -> big_int -> big_int

> Exponentiation functions. Return the big integer representing the first argument `a` raised to the power `b` (the second argument). Depending on the function, `a` and `b` can be either small integers or big integers. Raise `Invalid_argument` if `b` is negative.

Comparisons and tests

    val sign_big_int : big_int -> int

> Return `0` if the given big integer is zero, `1` if it is positive, and `-1` if it is negative.

    val compare_big_int : big_int -> big_int -> int

> `compare_big_int a b` returns `0` if `a` and `b` are equal, `1` if `a` is greater than `b`, and `-1` if `a` is smaller than `b`.

    val eq_big_int : big_int -> big_int -> bool
    val le_big_int : big_int -> big_int -> bool
    val ge_big_int : big_int -> big_int -> bool
    val lt_big_int : big_int -> big_int -> bool
    val gt_big_int : big_int -> big_int -> bool

> Usual boolean comparisons between two big integers.

    val max_big_int : big_int -> big_int -> big_int

> Return the greater of its two arguments.

    val min_big_int : big_int -> big_int -> big_int

> Return the smaller of its two arguments.

    val num_digits_big_int : big_int -> int

> Return the number of machine words used to store the given big integer.

Conversions to and from strings

    val string_of_big_int : big_int -> string

> Return the string representation of the given big integer, in decimal (base 10).

    val big_int_of_string : string -> big_int

> Convert a string to a big integer, in decimal. The string consists of an optional `-` or `+` sign, followed by one or several decimal digits.

Conversions to and from other numerical types

    val big_int_of_int : int -> big_int

> Convert a small integer to a big integer.

    val is_int_big_int : big_int -> bool

> Test whether the given big integer is small enough to be representable as a small integer (type `int`) without loss of precision. On a 32-bit platform, `is_int_big_int a` returns `true` if and only if `a` is between -230 and 230-1. On a 64-bit platform, `is_int_big_int a` returns `true` if and only if `a` is between -262 and 262-1.

    val int_of_big_int : big_int -> int

> Convert a big integer to a small integer (type `int`). Raises `Failure "int_of_big_int"` if the big integer is not representable as a small integer.

    val float_of_big_int : big_int -> float

> Returns a floating-point number approximating the given big integer.

21.3 | Module `Arith_status`: flags that control rational arithmetic

    val arith_status: unit -> unit

> Print the current status of the arithmetic flags.

    val get_error_when_null_denominator : unit -> bool
    val set_error_when_null_denominator : bool -> unit

> Get or set the flag `null_denominator`. When on, attempting to create a rational with a null denominator raises an exception. When off, rationals with null denominators are accepted. Initially: on.

    val get_normalize_ratio : unit -> bool
    val set_normalize_ratio : bool -> unit

> Get or set the flag `normalize_ratio`. When on, rational numbers are normalized after each operation. When off, rational numbers are not normalized until printed. Initially: off.

    val get_normalize_ratio_when_printing : unit -> bool
    val set_normalize_ratio_when_printing : bool -> unit

> Get or set the flag `normalize_ratio_when_printing`. When on, rational numbers are normalized before being printed. When off, rational numbers are printed as is, without normalization. Initially: on.

    val get_approx_printing : unit -> bool
    val set_approx_printing : bool -> unit

> Get or set the flag `approx_printing`. When on, rational numbers are printed as a decimal approximation. When off, rational numbers are printed as a fraction. Initially: off.

    val get_floating_precision : unit -> int
    val set_floating_precision : int -> unit

> Get or set the parameter `floating_precision`. This parameter is the number of digits displayed when `approx_printing` is on. Initially: 12.