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

The `num` library implements exact-precision rational arithmetic. It is built upon the state-of-the-art BigNum arbitrary-precision integer arithmetic package, and therefore achieves very high performance.
The functions provided in this library are fully documented 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`). A summary of the functions is given below.
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

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 `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.