Arbitrary-precision rational numbers.
Sexp conversions represent values as decimals if possible, or defaults to
(x + y/z) where
x is decimal and
z are integers. So for example, 1/3 <-> (0.333333333 + 1/3000000000). In string and sexp conversions, values with denominator of zero are special-cased: 0/0 <-> "nan", 1/0 <-> "inf", and -1/0 <-> "-inf".
include Core_kernel.Comparable with type t := t
include Base.Comparable.S with type t := t
include Base.Comparisons.S with type t := t
ascending is identical to
descending x y = ascending y x. These are intended to be mnemonic when used like
List.sort ~compare:ascending and
~cmp:descending, since they cause the list to be sorted in ascending or descending order, respectively.
clamp_exn t ~min ~max returns
t', the closest value to
t such that
between t' ~low:min ~high:max is true.
not (min <= max).
include Core_kernel.Hashable with type t := t
include Core_kernel.Binable with type t := t
This function only needs implementation if
t exposed to be a polymorphic variant. Despite what the type reads, this does *not* produce a function after reading; instead it takes the constructor tag (int) before reading and reads the rest of the variant
val bin_shape_t : Bin_prot.Shape.t
gen produces values with an order of magnitude (roughly the number of digits) in the numerator and denominator proportional to
Quickcheck.Generator.size. Also includes values with zero in the denominator.
val zero : t
val one : t
val ten : t
val hundred : t
val thousand : t
val million : t
val billion : t
val trillion : t
val tenth : t
val hundredth : t
val thousandth : t
val millionth : t
val billionth : t
val trillionth : t
val (//) : int -> int -> t
m // n is equivalent to
of_int m / of_int n. Example:
Bigint.O.(2 // 3).
2 ** 8_000_000 will take at least a megabyte to store the result, and multiplying numbers a megabyte long is slow no matter how clever your algorithm. Be careful to ensure the second argument is reasonably-sized.
Default rounding direction is
to_multiple_of defaults to
one and must not be
val iround : ?dir:[ `Down | `Up | `Nearest | `Zero ] -> ?to_multiple_of:int -> t -> int option
None if the result would overflow or
to_multiple_of is zero.
val iround_exn : ?dir:[ `Down | `Up | `Nearest | `Zero ] -> ?to_multiple_of:int -> t -> int
Exception if the result would overflow or
to_multiple_of is zero.
Convenience wrapper around
round to round to the specified number of decimal digits. This raises if the number is infinite or undefined.
val to_float : t -> float
val to_string_decimal_accurate_exn : t -> string
Accurate if possible. If this number is not representable as a finite decimal fraction, it raises instead.
As above, returns Or_error.t instead of raising
val is_representable_as_decimal : t -> bool
true if and only if
to_string_decimal_accurate_exn doesn't raise.
val is_real : t -> bool
true if and only if the number is non-infinity and non-undefined.
val is_nan : t -> bool
true if and only if the number is undefined.
val to_string_hum : ?delimiter:char -> ?decimals:int -> ?strip_zero:bool -> t -> string
Pretty print bignum in an approximate decimal form or print inf, -inf, nan. For example
to_string_hum ~delimiter:',' ~decimals:3 ~strip_zero:false 1234.1999 =
"1,234.200". No delimiters are inserted to the right of the decimal.
val to_string_accurate : t -> string
Always accurate. If the number is representable as a finite decimal, it will return this decimal string. If the denomiator is zero, it would return "nan", "inf" or "-inf". Finally, if the bignum is a rational non representable as a decimal,
to_string_accurate t returns an expression that evaluates to the right value. Example:
to_string_accurate (Bignum.of_string "1/3") = "(0.333333333 +
Since the introduction of that function in the API,
of_string is able to read any value returned by this function, and would yield the original bignum. That is:
fun bignum -> bignum |> to_string_accurate |> of_string
is the identity in
val of_float_decimal : float -> t
float into a
Bignum.t needs to be done with care. Most rationals and decimals are not exactly representable as floats, thus their float representation includes some small imprecision at the end of their decimal form (typically after the 17th digits). It is very likely that when transforming a
float into a
Bignum.t, it is best to try to determine which was the original value and retrieve it instead of honoring the noise coming from its imprecise float representation.
Given that the original value is not available in the context of a function whose type is
float -> Bignum.t, it is not possible to solve that problem in a principled way. However, a very reasonable approximation is to build the
Bignum from a short string-representation of the float that guarantees the round-trip
float |> to_string
|> of_string. In particular, if the float was obtained from a short decimal string, this heuristic in practice succeeds at retrieving the original value.
In the context where it is assumed that a float is a perfect representative of the value meant to be modelled, the actual
Bignum.t value for it may be built using
3.14 is not a representable decimal, thus:
of_float_dyadic (Float.of_string "3.14") = (3.14 + 7/56294995342131200)
of_float_decimal (Float.of_string "3.14") = 3.14
of_float_dyadic used to be called
of_float but we think it is not the right default choice, thus
of_float was deprecated, and we introduced different names for this operation to force some explicit decision at call site.
After some time has passed,
of_float_decimal will be renamed to
of_float, thus re-introducing
of_float in the API.
val of_float_dyadic : float -> t
val of_float : float -> t
val to_int : t -> int option
Rounds toward zero.
None if the conversion would overflow
val to_int_exn : t -> int
val is_zero : t -> bool
val sign : t -> int
val of_string : string -> t
val of_int : int -> t
gen_finite is like
gen but excludes values with zero in the denominator.
gen_uniform_excl lower_bound upper_bound produces a uniform distribution between
upper_bound, exclusive, in units based on the fractional parts of the bounds plus a number of decimal places proportional to
gen_incl lower_bound upper_bound produces a distribution of values between
upper_bound, inclusive, that is approximately uniform with extra weight given to producing the endpoints
module Stable : sig ... end
module O : sig ... end
val to_string : t -> string