(** Rationals. This modules builds arbitrary precision rationals on top of arbitrary integers from module Z. This file is part of the Zarith library http://forge.ocamlcore.org/projects/zarith . It is distributed under LGPL 2 licensing, with static linking exception. See the LICENSE file included in the distribution. Copyright (c) 2010-2011 Antoine Miné, Abstraction project. Abstraction is part of the LIENS (Laboratoire d'Informatique de l'ENS), a joint laboratory by: CNRS (Centre national de la recherche scientifique, France), ENS (École normale supérieure, Paris, France), INRIA Rocquencourt (Institut national de recherche en informatique, France). *) (** {1 Types} *) type t = { num: Z.t; (** Numerator. *) den: Z.t; (** Denominator, >= 0 *) } (** A rational is represented as a pair numerator/denominator, reduced to have a non-negative denominator and no common factor. This form is canonical (enabling polymorphic equality and hashing). The representation allows three special numbers: [inf] (1/0), [-inf] (-1/0) and [undef] (0/0). *) (** {1 Construction} *) val make: Z.t -> Z.t -> t (** [make num den] constructs a new rational equal to [num]/[den]. It takes care of putting the rational in canonical form. *) val zero: t val one: t val minus_one:t (** 0, 1, -1. *) val inf: t (** 1/0. *) val minus_inf: t (** -1/0. *) val undef: t (** 0/0. *) val of_bigint: Z.t -> t val of_int: int -> t val of_int32: int32 -> t val of_int64: int64 -> t val of_nativeint: nativeint -> t (** Conversions from various integer types. *) val of_ints: int -> int -> t (** Conversion from an [int] numerator and an [int] denominator. *) val of_float: float -> t (** Conversion from a [float]. The conversion is exact, and maps NaN to [undef]. *) val of_string: string -> t (** Converts a string to a rational. Plain integers, [/] separated integer ratios (with optional sign), decimal point and scientific notations are understood. Additionally, the special [inf], [-inf], and [undef] are recognized (they can also be typeset respectively as [1/0], [-1/0], [0/0]). *) (** {1 Inspection} *) val num: t -> Z.t (** Get the numerator. *) val den: t -> Z.t (** Get the denominator. *) (** {1 Testing} *) type kind = | ZERO (** 0 *) | INF (** infinity, i.e. 1/0 *) | MINF (** minus infinity, i.e. -1/0 *) | UNDEF (** undefined, i.e., 0/0 *) | NZERO (** well-defined, non-infinity, non-zero number *) (** Rationals can be categorized into different kinds, depending mainly on whether the numerator and/or denominator is null. *) val classify: t -> kind (** Determines the kind of a rational. *) val is_real: t -> bool (** Whether the argument is non-infinity and non-undefined. *) val sign: t -> int (** Returns 1 if the argument is positive (including inf), -1 if it is negative (including -inf), and 0 if it is null or undefined. *) val compare: t -> t -> int (** [compare x y] compares [x] to [y] and returns 1 if [x] is strictly greater that [y], -1 if it is strictly smaller, and 0 if they are equal. This is a total ordering. Infinities are ordered in the natural way, while undefined is considered the smallest of all: undef = undef < -inf <= -inf < x < inf <= inf. This is consistent with OCaml's handling of floating-point infinities and NaN. OCaml's polymorphic comparison will NOT return a result consistent with the ordering of rationals. *) val equal: t -> t -> bool (** Equality testing. Unlike [compare], this follows IEEE semantics: [undef] <> [undef]. *) val min: t -> t -> t (** Returns the smallest of its arguments. *) val max: t -> t -> t (** Returns the largest of its arguments. *) val leq: t -> t -> bool (** Less than or equal. [leq undef undef] returns false. *) val geq: t -> t -> bool (** Greater than or equal. [leq undef undef] returns false. *) val lt: t -> t -> bool (** Less than (not equal). *) val gt: t -> t -> bool (** Greater than (not equal). *) (** {1 Conversions} *) val to_bigint: t -> Z.t val to_int: t -> int val to_int32: t -> int32 val to_int64: t -> int64 val to_nativeint: t -> nativeint (** Convert to integer by truncation. Raises a [Divide_by_zero] if the argument is an infinity or undefined. Raises a [Z.Overflow] if the result does not fit in the destination type. *) val to_string: t -> string (** Converts to human-readable, base-10, [/]-separated rational. *) val to_float: t -> float (** Converts to a floating-point number, using the current floating-point rounding mode. With the default rounding mode, the result is the floating-point number closest to the given rational; ties break to even mantissa. *) (** {1 Arithmetic operations} *) (** In all operations, the result is [undef] if one argument is [undef]. Other operations can return [undef]: such as [inf]-[inf], [inf]*0, 0/0. *) val neg: t -> t (** Negation. *) val abs: t -> t (** Absolute value. *) val add: t -> t -> t (** Addition. *) val sub: t -> t -> t (** Subtraction. We have [sub x y] = [add x (neg y)]. *) val mul: t -> t -> t (** Multiplication. *) val inv: t -> t (** Inverse. Note that [inv 0] is defined, and equals [inf]. *) val div: t -> t -> t (** Division. We have [div x y] = [mul x (inv y)], and [inv x] = [div one x]. *) val mul_2exp: t -> int -> t (** [mul_2exp x n] multiplies [x] by 2 to the power of [n]. *) val div_2exp: t -> int -> t (** [div_2exp x n] divides [x] by 2 to the power of [n]. *) (** {1 Printing} *) val print: t -> unit (** Prints the argument on the standard output. *) val output: out_channel -> t -> unit (** Prints the argument on the specified channel. Also intended to be used as [%a] format printer in [Printf.printf]. *) val sprint: unit -> t -> string (** To be used as [%a] format printer in [Printf.sprintf]. *) val bprint: Buffer.t -> t -> unit (** To be used as [%a] format printer in [Printf.bprintf]. *) val pp_print: Format.formatter -> t -> unit (** Prints the argument on the specified formatter. Also intended to be used as [%a] format printer in [Format.printf]. *) (** {1 Prefix and infix operators} *) (** Classic prefix and infix [int] operators are redefined on [t]. *) val (~-): t -> t (** Negation [neg]. *) val (~+): t -> t (** Identity. *) val (+): t -> t -> t (** Addition [add]. *) val (-): t -> t -> t (** Subtraction [sub]. *) val ( * ): t -> t -> t (** Multiplication [mul]. *) val (/): t -> t -> t (** Division [div]. *) val (lsl): t -> int -> t (** Multiplication by a power of two [mul_2exp]. *) val (asr): t -> int -> t (** Division by a power of two [shift_right]. *) val (~$): int -> t (** Conversion from [int]. *) val (//): int -> int -> t (** Creates a rational from two [int]s. *) val (~$$): Z.t -> t (** Conversion from [Z.t]. *) val (///): Z.t -> Z.t -> t (** Creates a rational from two [Z.t]. *) val (=): t -> t -> bool (** Same as [equal]. @since 1.8 *) val (<): t -> t -> bool (** Same as [lt]. @since 1.8 *) val (>): t -> t -> bool (** Same as [gt]. @since 1.8 *) val (<=): t -> t -> bool (** Same as [leq]. @since 1.8 *) val (>=): t -> t -> bool (** Same as [geq]. @since 1.8 *) val (<>): t -> t -> bool (** [a <> b] is equivalent to [not (equal a b)]. @since 1.8 *)