880 lines
27 KiB
OCaml
880 lines
27 KiB
OCaml
(**
|
|
Integers.
|
|
|
|
This modules provides arbitrary-precision integers.
|
|
Small integers internally use a regular OCaml [int].
|
|
When numbers grow too large, we switch transparently to GMP numbers
|
|
([mpn] numbers fully allocated on the OCaml heap).
|
|
|
|
This interface is rather similar to that of [Int32] and [Int64],
|
|
with some additional functions provided natively by GMP
|
|
(GCD, square root, pop-count, etc.).
|
|
|
|
|
|
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 Toplevel} *)
|
|
|
|
(** For an optimal experience with the [ocaml] interactive toplevel,
|
|
the magic commands are:
|
|
|
|
{[
|
|
#load "zarith.cma";;
|
|
#install_printer Z.pp_print;;
|
|
]}
|
|
|
|
Alternatively, using the new [Zarith_top] toplevel module, simply:
|
|
{[
|
|
#require "zarith.top";;
|
|
]}
|
|
*)
|
|
|
|
|
|
|
|
(** {1 Types} *)
|
|
|
|
type t
|
|
(** Type of integers of arbitrary length. *)
|
|
|
|
exception Overflow
|
|
(** Raised by conversion functions when the value cannot be represented in
|
|
the destination type.
|
|
*)
|
|
|
|
(** {1 Construction} *)
|
|
|
|
val zero: t
|
|
(** The number 0. *)
|
|
|
|
val one: t
|
|
(** The number 1. *)
|
|
|
|
val minus_one: t
|
|
(** The number -1. *)
|
|
|
|
external of_int: int -> t = "%identity"
|
|
(** Converts from a base integer. *)
|
|
|
|
external of_int32: int32 -> t = "ml_z_of_int32"
|
|
(** Converts from a 32-bit (signed) integer. *)
|
|
|
|
external of_int64: int64 -> t = "ml_z_of_int64"
|
|
(** Converts from a 64-bit (signed) integer. *)
|
|
|
|
external of_nativeint: nativeint -> t = "ml_z_of_nativeint"
|
|
(** Converts from a native (signed) integer. *)
|
|
|
|
val of_int32_unsigned: int32 -> t
|
|
(** Converts from a 32-bit integer, interpreted as an unsigned integer.
|
|
@since 1.13
|
|
*)
|
|
|
|
val of_int64_unsigned: int64 -> t
|
|
(** Converts from a 64-bit integer, interpreted as an unsigned integer.
|
|
@since 1.13
|
|
*)
|
|
|
|
val of_nativeint_unsigned: nativeint -> t
|
|
(** Converts from a native integer, interpreted as an unsigned integer..
|
|
@since 1.13
|
|
*)
|
|
|
|
external of_float: float -> t = "ml_z_of_float"
|
|
(** Converts from a floating-point value.
|
|
The value is truncated (rounded towards zero).
|
|
Raises [Overflow] on infinity and NaN arguments.
|
|
*)
|
|
|
|
val of_string: string -> t
|
|
(** Converts a string to an integer.
|
|
An optional [-] prefix indicates a negative number, while a [+]
|
|
prefix is ignored.
|
|
An optional prefix [0x], [0o], or [0b] (following the optional [-]
|
|
or [+] prefix) indicates that the number is,
|
|
represented, in hexadecimal, octal, or binary, respectively.
|
|
Otherwise, base 10 is assumed.
|
|
(Unlike C, a lone [0] prefix does not denote octal.)
|
|
Raises an [Invalid_argument] exception if the string is not a
|
|
syntactically correct representation of an integer.
|
|
*)
|
|
|
|
val of_substring : string -> pos:int -> len:int -> t
|
|
(** [of_substring s ~pos ~len] is the same as [of_string (String.sub s
|
|
pos len)]
|
|
@since 1.4
|
|
*)
|
|
|
|
val of_string_base: int -> string -> t
|
|
(** Parses a number represented as a string in the specified base,
|
|
with optional [-] or [+] prefix.
|
|
The base must be between 2 and 16.
|
|
*)
|
|
|
|
external of_substring_base
|
|
: int -> string -> pos:int -> len:int -> t
|
|
= "ml_z_of_substring_base"
|
|
(** [of_substring_base base s ~pos ~len] is the same as [of_string_base
|
|
base (String.sub s pos len)]
|
|
@since 1.4
|
|
*)
|
|
|
|
|
|
(** {1 Basic arithmetic operations} *)
|
|
|
|
val succ: t -> t
|
|
(** Returns its argument plus one. *)
|
|
|
|
val pred: t -> t
|
|
(** Returns its argument minus one. *)
|
|
|
|
val abs: t -> t
|
|
(** Absolute value. *)
|
|
|
|
val neg: t -> t
|
|
(** Unary negation. *)
|
|
|
|
val add: t -> t -> t
|
|
(** Addition. *)
|
|
|
|
val sub: t -> t -> t
|
|
(** Subtraction. *)
|
|
|
|
val mul: t -> t -> t
|
|
(** Multiplication. *)
|
|
|
|
val div: t -> t -> t
|
|
(** Integer division. The result is truncated towards zero
|
|
and obeys the rule of signs.
|
|
Raises [Division_by_zero] if the divisor (second argument) is 0.
|
|
*)
|
|
|
|
val rem: t -> t -> t
|
|
(** Integer remainder. Can raise a [Division_by_zero].
|
|
The result of [rem a b] has the sign of [a], and its absolute value is
|
|
strictly smaller than the absolute value of [b].
|
|
The result satisfies the equality [a = b * div a b + rem a b].
|
|
*)
|
|
|
|
external div_rem: t -> t -> (t * t) = "ml_z_div_rem"
|
|
(** Computes both the integer quotient and the remainder.
|
|
[div_rem a b] is equal to [(div a b, rem a b)].
|
|
Raises [Division_by_zero] if [b = 0].
|
|
*)
|
|
|
|
external cdiv: t -> t -> t = "ml_z_cdiv"
|
|
(** Integer division with rounding towards +oo (ceiling).
|
|
Can raise a [Division_by_zero].
|
|
*)
|
|
|
|
external fdiv: t -> t -> t = "ml_z_fdiv"
|
|
(** Integer division with rounding towards -oo (floor).
|
|
Can raise a [Division_by_zero].
|
|
*)
|
|
|
|
val ediv_rem: t -> t -> (t * t)
|
|
(** Euclidean division and remainder. [ediv_rem a b] returns a pair [(q, r)]
|
|
such that [a = b * q + r] and [0 <= r < |b|].
|
|
Raises [Division_by_zero] if [b = 0].
|
|
*)
|
|
|
|
val ediv: t -> t -> t
|
|
(** Euclidean division. [ediv a b] is equal to [fst (ediv_rem a b)].
|
|
The result satisfies [0 <= a - b * ediv a b < |b|].
|
|
Raises [Division_by_zero] if [b = 0].
|
|
*)
|
|
|
|
val erem: t -> t -> t
|
|
(** Euclidean remainder. [erem a b] is equal to [snd (ediv_rem a b)].
|
|
The result satisfies [0 <= erem a b < |b|] and
|
|
[a = b * ediv a b + erem a b]. Raises [Division_by_zero] if [b = 0].
|
|
*)
|
|
|
|
val divexact: t -> t -> t
|
|
(** [divexact a b] divides [a] by [b], only producing correct result when the
|
|
division is exact, i.e., when [b] evenly divides [a].
|
|
It should be faster than general division.
|
|
Can raise a [Division_by_zero].
|
|
*)
|
|
|
|
val divisible: t -> t -> bool
|
|
(** [divisible a b] returns [true] if [a] is exactly divisible by [b].
|
|
Unlike the other division functions, [b = 0] is accepted
|
|
(only 0 is considered divisible by 0).
|
|
@since 1.10
|
|
*)
|
|
|
|
external congruent: t -> t -> t -> bool = "ml_z_congruent"
|
|
(** [congruent a b c] returns [true] if [a] is congruent to [b] modulo [c].
|
|
Unlike the other division functions, [c = 0] is accepted
|
|
(only equal numbers are considered equal congruent 0).
|
|
@since 1.10
|
|
*)
|
|
|
|
|
|
|
|
|
|
(** {1 Bit-level operations} *)
|
|
|
|
(** For all bit-level operations, negative numbers are considered in 2's
|
|
complement representation, starting with a virtual infinite number of
|
|
1s.
|
|
*)
|
|
|
|
val logand: t -> t -> t
|
|
(** Bitwise logical and. *)
|
|
|
|
val logor: t -> t -> t
|
|
(** Bitwise logical or. *)
|
|
|
|
val logxor: t -> t -> t
|
|
(** Bitwise logical exclusive or. *)
|
|
|
|
val lognot: t -> t
|
|
(** Bitwise logical negation.
|
|
The identity [lognot a]=[-a-1] always hold.
|
|
*)
|
|
|
|
val shift_left: t -> int -> t
|
|
(** Shifts to the left.
|
|
Equivalent to a multiplication by a power of 2.
|
|
The second argument must be nonnegative.
|
|
*)
|
|
|
|
val shift_right: t -> int -> t
|
|
(** Shifts to the right.
|
|
This is an arithmetic shift,
|
|
equivalent to a division by a power of 2 with rounding towards -oo.
|
|
The second argument must be nonnegative.
|
|
*)
|
|
|
|
val shift_right_trunc: t -> int -> t
|
|
(** Shifts to the right, rounding towards 0.
|
|
This is equivalent to a division by a power of 2, with truncation.
|
|
The second argument must be nonnegative.
|
|
*)
|
|
|
|
external numbits: t -> int = "ml_z_numbits" [@@noalloc]
|
|
(** Returns the number of significant bits in the given number.
|
|
If [x] is zero, [numbits x] returns 0. Otherwise,
|
|
[numbits x] returns a positive integer [n] such that
|
|
[2^{n-1} <= |x| < 2^n]. Note that [numbits] is defined
|
|
for negative arguments, and that [numbits (-x) = numbits x].
|
|
@since 1.4
|
|
*)
|
|
|
|
external trailing_zeros: t -> int = "ml_z_trailing_zeros" [@@noalloc]
|
|
(** Returns the number of trailing 0 bits in the given number.
|
|
If [x] is zero, [trailing_zeros x] returns [max_int].
|
|
Otherwise, [trailing_zeros x] returns a nonnegative integer [n]
|
|
which is the largest [n] such that [2^n] divides [x] evenly.
|
|
Note that [trailing_zeros] is defined for negative arguments,
|
|
and that [trailing_zeros (-x) = trailing_zeros x].
|
|
@since 1.4
|
|
*)
|
|
|
|
val testbit: t -> int -> bool
|
|
(** [testbit x n] return the value of bit number [n] in [x]:
|
|
[true] if the bit is 1, [false] if the bit is 0.
|
|
Bits are numbered from 0. Raise [Invalid_argument] if [n]
|
|
is negative.
|
|
@since 1.4
|
|
*)
|
|
|
|
external popcount: t -> int = "ml_z_popcount"
|
|
(** Counts the number of bits set.
|
|
Raises [Overflow] for negative arguments, as those have an infinite
|
|
number of bits set.
|
|
*)
|
|
|
|
external hamdist: t -> t -> int = "ml_z_hamdist"
|
|
(** Counts the number of different bits.
|
|
Raises [Overflow] if the arguments have different signs
|
|
(in which case the distance is infinite).
|
|
*)
|
|
|
|
(** {1 Conversions} *)
|
|
|
|
(** Note that, when converting to an integer type that cannot represent the
|
|
converted value, an [Overflow] exception is raised.
|
|
*)
|
|
|
|
val to_int: t -> int
|
|
(** Converts to a signed OCaml [int].
|
|
Raises an [Overflow] if the value does not fit in a signed OCaml [int]. *)
|
|
|
|
external to_int32: t -> int32 = "ml_z_to_int32"
|
|
(** Converts to a signed 32-bit integer [int32].
|
|
Raises an [Overflow] if the value does not fit in a signed [int32]. *)
|
|
|
|
external to_int64: t -> int64 = "ml_z_to_int64"
|
|
(** Converts to a signed 64-bit integer [int64].
|
|
Raises an [Overflow] if the value does not fit in a signed [int64]. *)
|
|
|
|
external to_nativeint: t -> nativeint = "ml_z_to_nativeint"
|
|
(** Converts to a native signed integer [nativeint].
|
|
Raises an [Overflow] if the value does not fit in a signed [nativeint]. *)
|
|
|
|
external to_int32_unsigned: t -> int32 = "ml_z_to_int32_unsigned"
|
|
(** Converts to an unsigned 32-bit integer.
|
|
The result is stored into an OCaml [int32].
|
|
Beware that most [Int32] operations consider [int32] to a signed type, not unsigned.
|
|
Raises an [Overflow] if the value is negative or does not fit in an unsigned 32-bit integer.
|
|
@since 1.13
|
|
*)
|
|
|
|
external to_int64_unsigned: t -> int64 = "ml_z_to_int64_unsigned"
|
|
(** Converts to an unsigned 64-bit integer.
|
|
The result is stored into an OCaml [int64].
|
|
Beware that most [Int64] operations consider [int64] to a signed type, not unsigned.
|
|
Raises an [Overflow] if the value is negative or does not fit in an unsigned 64-bit integer.
|
|
@since 1.13
|
|
*)
|
|
|
|
external to_nativeint_unsigned: t -> nativeint = "ml_z_to_nativeint_unsigned"
|
|
(** Converts to a native unsigned integer.
|
|
The result is stored into an OCaml [nativeint].
|
|
Beware that most [Nativeint] operations consider [nativeint] to a signed type, not unsigned.
|
|
Raises an [Overflow] if the value is negative or does not fit in an unsigned native integer.
|
|
@since 1.13
|
|
*)
|
|
|
|
val to_float: t -> float
|
|
(** Converts to a floating-point value.
|
|
This function rounds the given integer according to the current
|
|
rounding mode of the processor. In default mode, it returns
|
|
the floating-point number nearest to the given integer,
|
|
breaking ties by rounding to even. *)
|
|
|
|
val to_string: t -> string
|
|
(** Gives a human-readable, decimal string representation of the argument. *)
|
|
|
|
external format: string -> t -> string = "ml_z_format"
|
|
(** Gives a string representation of the argument in the specified
|
|
printf-like format.
|
|
The general specification has the following form:
|
|
|
|
[% \[flags\] \[width\] type]
|
|
|
|
Where the type actually indicates the base:
|
|
|
|
- [i], [d], [u]: decimal
|
|
- [b]: binary
|
|
- [o]: octal
|
|
- [x]: lowercase hexadecimal
|
|
- [X]: uppercase hexadecimal
|
|
|
|
Supported flags are:
|
|
|
|
- [+]: prefix positive numbers with a [+] sign
|
|
- space: prefix positive numbers with a space
|
|
- [-]: left-justify (default is right justification)
|
|
- [0]: pad with zeroes (instead of spaces)
|
|
- [#]: alternate formatting (actually, simply output a literal-like prefix: [0x], [0b], [0o])
|
|
|
|
Unlike the classic [printf], all numbers are signed (even hexadecimal ones),
|
|
there is no precision field, and characters that are not part of the format
|
|
are simply ignored (and not copied in the output).
|
|
*)
|
|
|
|
external fits_int: t -> bool = "ml_z_fits_int" [@@noalloc]
|
|
(** Whether the argument fits in an OCaml signed [int]. *)
|
|
|
|
external fits_int32: t -> bool = "ml_z_fits_int32" [@@noalloc]
|
|
(** Whether the argument fits in a signed [int32]. *)
|
|
|
|
external fits_int64: t -> bool = "ml_z_fits_int64" [@@noalloc]
|
|
(** Whether the argument fits in a signed [int64]. *)
|
|
|
|
external fits_nativeint: t -> bool = "ml_z_fits_nativeint" [@@noalloc]
|
|
(** Whether the argument fits in a signed [nativeint]. *)
|
|
|
|
external fits_int32_unsigned: t -> bool = "ml_z_fits_int32_unsigned" [@@noalloc]
|
|
(** Whether the argument is non-negative and fits in an unsigned [int32].
|
|
@since 1.13
|
|
*)
|
|
|
|
external fits_int64_unsigned: t -> bool = "ml_z_fits_int64_unsigned" [@@noalloc]
|
|
(** Whether the argument is non-negative and fits in an unsigned [int64].
|
|
@since 1.13
|
|
*)
|
|
|
|
external fits_nativeint_unsigned: t -> bool = "ml_z_fits_nativeint_unsigned" [@@noalloc]
|
|
(** Whether the argument is non-negative fits in an unsigned [nativeint].
|
|
@since 1.13
|
|
*)
|
|
|
|
|
|
(** {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.
|
|
Can be used as [%a] format printer in [Format.printf] and as
|
|
argument to [#install_printer] in the top-level.
|
|
*)
|
|
|
|
|
|
(** {1 Ordering} *)
|
|
|
|
external compare: t -> t -> int = "ml_z_compare" [@@noalloc]
|
|
(** Comparison. [compare x y] returns 0 if [x] equals [y],
|
|
-1 if [x] is smaller than [y], and 1 if [x] is greater than [y].
|
|
|
|
Note that Pervasive.compare can be used to compare reliably two integers
|
|
only on OCaml 3.12.1 and later versions.
|
|
*)
|
|
|
|
external equal: t -> t -> bool = "ml_z_equal" [@@noalloc]
|
|
(** Equality test. *)
|
|
|
|
val leq: t -> t -> bool
|
|
(** Less than or equal. *)
|
|
|
|
val geq: t -> t -> bool
|
|
(** Greater than or equal. *)
|
|
|
|
val lt: t -> t -> bool
|
|
(** Less than (and not equal). *)
|
|
|
|
val gt: t -> t -> bool
|
|
(** Greater than (and not equal). *)
|
|
|
|
external sign: t -> int = "ml_z_sign" [@@noalloc]
|
|
(** Returns -1, 0, or 1 when the argument is respectively negative, null, or
|
|
positive.
|
|
*)
|
|
|
|
val min: t -> t -> t
|
|
(** Returns the minimum of its arguments. *)
|
|
|
|
val max: t -> t -> t
|
|
(** Returns the maximum of its arguments. *)
|
|
|
|
val is_even: t -> bool
|
|
(** Returns true if the argument is even (divisible by 2), false if odd.
|
|
@since 1.4
|
|
*)
|
|
|
|
val is_odd: t -> bool
|
|
(** Returns true if the argument is odd, false if even.
|
|
@since 1.4
|
|
*)
|
|
|
|
val hash: t -> int
|
|
(** Hashes a number, producing a small integer.
|
|
The result is consistent with equality:
|
|
if [a] = [b], then [hash a] = [hash b].
|
|
The result is the same as produced by OCaml's generic hash function,
|
|
{!Hashtbl.hash}.
|
|
Together with type {!Z.t}, the function {!Z.hash} makes it possible
|
|
to pass module {!Z} as argument to the functor {!Hashtbl.Make}.
|
|
@before 1.14 a different hash algorithm was used.
|
|
*)
|
|
|
|
val seeded_hash: int -> t -> int
|
|
(** Like {!Z.hash}, but takes a seed as extra argument for diversification.
|
|
The result is the same as produced by OCaml's generic seeded hash function,
|
|
{!Hashtbl.seeded_hash}.
|
|
Together with type {!Z.t}, the function {!Z.hash} makes it possible
|
|
to pass module {!Z} as argument to the functor {!Hashtbl.MakeSeeded}.
|
|
@since 1.14
|
|
*)
|
|
|
|
(** {1 Elementary number theory} *)
|
|
|
|
external gcd: t -> t -> t = "ml_z_gcd"
|
|
(** Greatest common divisor.
|
|
The result is always nonnegative.
|
|
We have [gcd(a,0) = gcd(0,a) = abs(a)], including [gcd(0,0) = 0].
|
|
*)
|
|
|
|
val gcdext: t -> t -> (t * t * t)
|
|
(** [gcdext u v] returns [(g,s,t)] where [g] is the greatest common divisor
|
|
and [g=us+vt].
|
|
[g] is always nonnegative.
|
|
|
|
Note: the function is based on the GMP [mpn_gcdext] function. The exact choice of [s] and [t] such that [g=us+vt] is not specified, as it may vary from a version of GMP to another (it has changed notably in GMP 4.3.0 and 4.3.1).
|
|
*)
|
|
|
|
val lcm: t -> t -> t
|
|
(**
|
|
Least common multiple.
|
|
The result is always nonnegative.
|
|
We have [lcm(a,0) = lcm(0,a) = 0].
|
|
*)
|
|
|
|
external powm: t -> t -> t -> t = "ml_z_powm"
|
|
(** [powm base exp mod] computes [base]^[exp] modulo [mod].
|
|
Negative [exp] are supported, in which case ([base]^-1)^(-[exp]) modulo
|
|
[mod] is computed.
|
|
However, if [exp] is negative but [base] has no inverse modulo [mod], then
|
|
a [Division_by_zero] is raised.
|
|
*)
|
|
|
|
external powm_sec: t -> t -> t -> t = "ml_z_powm_sec"
|
|
(** [powm_sec base exp mod] computes [base]^[exp] modulo [mod].
|
|
Unlike [Z.powm], this function is designed to take the same time
|
|
and have the same cache access patterns for any two same-size
|
|
arguments. Used in cryptographic applications, it provides better
|
|
resistance to side-channel attacks than [Z.powm].
|
|
The exponent [exp] must be positive, and the modulus [mod]
|
|
must be odd. Otherwise, [Invalid_arg] is raised.
|
|
@since 1.4
|
|
*)
|
|
|
|
external invert: t -> t -> t = "ml_z_invert"
|
|
(** [invert base mod] returns the inverse of [base] modulo [mod].
|
|
Raises a [Division_by_zero] if [base] is not invertible modulo [mod].
|
|
*)
|
|
|
|
external probab_prime: t -> int -> int = "ml_z_probab_prime"
|
|
(** [probab_prime x r] returns 0 if [x] is definitely composite,
|
|
1 if [x] is probably prime, and 2 if [x] is definitely prime.
|
|
The [r] argument controls how many Miller-Rabin probabilistic
|
|
primality tests are performed (5 to 10 is a reasonable value).
|
|
*)
|
|
|
|
external nextprime: t -> t = "ml_z_nextprime"
|
|
(** Returns the next prime greater than the argument.
|
|
The result is only prime with very high probability.
|
|
*)
|
|
|
|
external jacobi: t -> t -> int = "ml_z_jacobi"
|
|
(** [jacobi a b] returns the Jacobi symbol [(a/b)].
|
|
@since 1.10 *)
|
|
|
|
external legendre: t -> t -> int = "ml_z_legendre"
|
|
(** [legendre a b] returns the Legendre symbol [(a/b)].
|
|
@since 1.10 *)
|
|
|
|
external kronecker: t -> t -> int = "ml_z_kronecker"
|
|
(** [kronecker a b] returns the Kronecker symbol [(a/b)].
|
|
@since 1.10 *)
|
|
|
|
external remove: t -> t -> t * int = "ml_z_remove"
|
|
(** [remove a b] returns [a] after removing all the occurences of the
|
|
factor [b].
|
|
Also returns how many occurrences were removed.
|
|
@since 1.10 *)
|
|
|
|
external fac: int -> t = "ml_z_fac"
|
|
(** [fac n] returns the factorial of [n] ([n!]).
|
|
Raises an [Invaid_argument] if [n] is non-positive.
|
|
@since 1.10 *)
|
|
|
|
external fac2: int -> t = "ml_z_fac2"
|
|
(** [fac2 n] returns the double factorial of [n] ([n!!]).
|
|
Raises an [Invaid_argument] if [n] is non-positive.
|
|
@since 1.10 *)
|
|
|
|
external facM: int -> int -> t = "ml_z_facM"
|
|
(** [facM n m] returns the [m]-th factorial of [n].
|
|
Raises an [Invaid_argument] if [n] or [m] is non-positive.
|
|
@since 1.10 *)
|
|
|
|
external primorial: int -> t = "ml_z_primorial"
|
|
(** [primorial n] returns the product of all positive prime numbers less
|
|
than or equal to [n].
|
|
Raises an [Invaid_argument] if [n] is non-positive.
|
|
@since 1.10 *)
|
|
|
|
external bin: t -> int -> t = "ml_z_bin"
|
|
(** [bin n k] returns the binomial coefficient [n] over [k].
|
|
Raises an [Invaid_argument] if [k] is non-positive.
|
|
@since 1.10 *)
|
|
|
|
external fib: int -> t = "ml_z_fib"
|
|
(** [fib n] returns the [n]-th Fibonacci number.
|
|
Raises an [Invaid_argument] if [n] is non-positive.
|
|
@since 1.10 *)
|
|
|
|
external lucnum: int -> t = "ml_z_lucnum"
|
|
(** [lucnum n] returns the [n]-th Lucas number.
|
|
Raises an [Invaid_argument] if [n] is non-positive.
|
|
@since 1.10 *)
|
|
|
|
|
|
(** {1 Powers} *)
|
|
|
|
external pow: t -> int -> t = "ml_z_pow"
|
|
(** [pow base exp] raises [base] to the [exp] power.
|
|
[exp] must be nonnegative.
|
|
Note that only exponents fitting in a machine integer are supported, as
|
|
larger exponents would surely make the result's size overflow the
|
|
address space.
|
|
*)
|
|
|
|
external sqrt: t -> t = "ml_z_sqrt"
|
|
(** Returns the square root. The result is truncated (rounded down
|
|
to an integer).
|
|
Raises an [Invalid_argument] on negative arguments.
|
|
*)
|
|
|
|
external sqrt_rem: t -> (t * t) = "ml_z_sqrt_rem"
|
|
(** Returns the square root truncated, and the remainder.
|
|
Raises an [Invalid_argument] on negative arguments.
|
|
*)
|
|
|
|
external root: t -> int -> t = "ml_z_root"
|
|
(** [root x n] computes the [n]-th root of [x].
|
|
[n] must be positive and, if [n] is even, then [x] must be nonnegative.
|
|
Otherwise, an [Invalid_argument] is raised.
|
|
*)
|
|
|
|
external rootrem: t -> int -> t * t = "ml_z_rootrem"
|
|
(** [rootrem x n] computes the [n]-th root of [x] and the remainder
|
|
[x-root**n].
|
|
[n] must be positive and, if [n] is even, then [x] must be nonnegative.
|
|
Otherwise, an [Invalid_argument] is raised.
|
|
@since 1.10 *)
|
|
|
|
external perfect_power: t -> bool = "ml_z_perfect_power"
|
|
(** True if the argument has the form [a^b], with [b>1] *)
|
|
|
|
external perfect_square: t -> bool = "ml_z_perfect_square"
|
|
(** True if the argument has the form [a^2]. *)
|
|
|
|
val log2: t -> int
|
|
(** Returns the base-2 logarithm of its argument, rounded down to
|
|
an integer. If [x] is positive, [log2 x] returns the largest [n]
|
|
such that [2^n <= x]. If [x] is negative or zero, [log2 x] raise
|
|
the [Invalid_argument] exception.
|
|
@since 1.4
|
|
*)
|
|
|
|
val log2up: t -> int
|
|
(** Returns the base-2 logarithm of its argument, rounded up to
|
|
an integer. If [x] is positive, [log2up x] returns the smallest [n]
|
|
such that [x <= 2^n]. If [x] is negative or zero, [log2up x] raise
|
|
the [Invalid_argument] exception.
|
|
@since 1.4
|
|
*)
|
|
|
|
(** {1 Representation} *)
|
|
|
|
external size: t -> int = "ml_z_size" [@@noalloc]
|
|
(** Returns the number of machine words used to represent the number. *)
|
|
|
|
val extract: t -> int -> int -> t
|
|
(** [extract a off len] returns a nonnegative number corresponding to bits
|
|
[off] to [off]+[len]-1 of [a].
|
|
Negative [a] are considered in infinite-length 2's complement
|
|
representation.
|
|
Raises an [Invalid_argument] if [off] is strictly negative, or if [len] is negative or null.
|
|
*)
|
|
|
|
val signed_extract: t -> int -> int -> t
|
|
(** [signed_extract a off len] extracts bits [off] to [off]+[len]-1 of [b],
|
|
as [extract] does, then sign-extends bit [len-1] of the result
|
|
(that is, bit [off + len - 1] of [a]). The result is between
|
|
[- 2{^[len]-1}] (included) and [2{^[len]-1}] (excluded),
|
|
and equal to [extract a off len] modulo [2{^len}].
|
|
Raises an [Invalid_argument] if [off] is strictly negative, or if [len] is negative or null.
|
|
*)
|
|
|
|
external to_bits: t -> string = "ml_z_to_bits"
|
|
(** Returns a binary representation of the argument.
|
|
The string result should be interpreted as a sequence of bytes,
|
|
corresponding to the binary representation of the absolute value of
|
|
the argument in little endian ordering.
|
|
The sign is not stored in the string.
|
|
*)
|
|
|
|
external of_bits: string -> t = "ml_z_of_bits"
|
|
(** Constructs a number from a binary string representation.
|
|
The string is interpreted as a sequence of bytes in little endian order,
|
|
and the result is always positive.
|
|
We have the identity: [of_bits (to_bits x) = abs x].
|
|
However, we can have [to_bits (of_bits s) <> s] due to the presence of
|
|
trailing zeros in s.
|
|
*)
|
|
|
|
(** {1 Pseudo-random number generation} *)
|
|
|
|
val random_int: ?rng: Random.State.t -> t -> t
|
|
(** [random_int bound] returns a random integer between 0 (inclusive)
|
|
and [bound] (exclusive). [bound] must be greater than 0.
|
|
|
|
The source of randomness is the {!Random} module from the OCaml
|
|
standard library. The optional [rng] argument specifies which
|
|
random state to use. If omitted, the default random state for the
|
|
{!Random} module is used.
|
|
|
|
Random numbers produced by this function are not cryptographically
|
|
strong and must not be used in cryptographic or high-security
|
|
contexts. See {!Z.random_int_gen} for an alternative.
|
|
|
|
@since 1.13
|
|
*)
|
|
|
|
val random_bits: ?rng: Random.State.t -> int -> t
|
|
(** [random_bits nbits] returns a random integer between 0 (inclusive)
|
|
and [2{^nbits}] (exclusive). [nbits] must be nonnegative.
|
|
This is a more efficient special case of {!Z.random_int} when the
|
|
bound is a power of two.
|
|
|
|
The source of randomness and the [rng] optional argument are as
|
|
described in {!Z.random_int}.
|
|
|
|
Random numbers produced by this function are not cryptographically
|
|
strong and must not be used in cryptographic or high-security
|
|
contexts. See {!Z.random_bits_gen} for an alternative.
|
|
|
|
@since 1.13
|
|
*)
|
|
|
|
val random_int_gen: fill: (bytes -> int -> int -> unit) -> t -> t
|
|
(** [random_int_gen ~fill bound] returns a random integer between 0 (inclusive)
|
|
and [bound] (exclusive). [bound] must be greater than 0.
|
|
|
|
The [fill] parameter is the source of randomness. It is called
|
|
as [fill buf pos len], and is responsible for drawing [len] random
|
|
bytes and writing them to offsets [pos] to [pos + len - 1] of
|
|
the byte array [buf].
|
|
|
|
Example of use where [/dev/random] provides the random bytes:
|
|
<<
|
|
In_channel.with_open_bin "/dev/random"
|
|
(fun ic -> Z.random_int_gen ~fill:(really_input ic) bound)
|
|
>>
|
|
Example of use where the Cryptokit library provides the random bytes:
|
|
<<
|
|
Z.random_int_gen ~fill:Cryptokit.Random.secure_rng#bytes bound
|
|
>>
|
|
@since 1.13
|
|
*)
|
|
|
|
val random_bits_gen: fill: (bytes -> int -> int -> unit) -> int -> t
|
|
(** [random_bits_gen ~fill nbits] returns a random integer between 0 (inclusive)
|
|
and [2{^nbits}] (exclusive). [nbits] must be nonnegative.
|
|
This is a more efficient special case of {!Z.random_int_gen} when the
|
|
bound is a power of two. The [fill] parameter is as described in
|
|
{!Z.random_int_gen}.
|
|
@since 1.13
|
|
*)
|
|
|
|
(** {1 Prefix and infix operators} *)
|
|
|
|
(**
|
|
Classic (and less classic) prefix and infix [int] operators are
|
|
redefined on [t].
|
|
|
|
This makes it easy to typeset expressions.
|
|
Using OCaml 3.12's local open, you can simply write
|
|
[Z.(~$2 + ~$5 * ~$10)].
|
|
*)
|
|
|
|
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
|
|
(** Truncated division [div]. *)
|
|
|
|
external (/>): t -> t -> t = "ml_z_cdiv"
|
|
(** Ceiling division [cdiv]. *)
|
|
|
|
external (/<): t -> t -> t = "ml_z_fdiv"
|
|
(** Flooring division [fdiv]. *)
|
|
|
|
val (/|): t -> t -> t
|
|
(** Exact division [divexact]. *)
|
|
|
|
val (mod): t -> t -> t
|
|
(** Remainder [rem]. *)
|
|
|
|
val (land): t -> t -> t
|
|
(** Bit-wise logical and [logand]. *)
|
|
|
|
val (lor): t -> t -> t
|
|
(** Bit-wise logical inclusive or [logor]. *)
|
|
|
|
val (lxor): t -> t -> t
|
|
(** Bit-wise logical exclusive or [logxor]. *)
|
|
|
|
val (~!): t -> t
|
|
(** Bit-wise logical negation [lognot]. *)
|
|
|
|
val (lsl): t -> int -> t
|
|
(** Bit-wise shift to the left [shift_left]. *)
|
|
|
|
val (asr): t -> int -> t
|
|
(** Bit-wise shift to the right [shift_right]. *)
|
|
|
|
external (~$): int -> t = "%identity"
|
|
|
|
(** Conversion from [int] [of_int]. *)
|
|
|
|
external ( ** ): t -> int -> t = "ml_z_pow"
|
|
(** Power [pow]. *)
|
|
|
|
module Compare : sig
|
|
|
|
val (=): t -> t -> bool
|
|
(** Same as [equal]. *)
|
|
|
|
val (<): t -> t -> bool
|
|
(** Same as [lt]. *)
|
|
|
|
val (>): t -> t -> bool
|
|
(** Same as [gt]. *)
|
|
|
|
val (<=): t -> t -> bool
|
|
(** Same as [leq]. *)
|
|
|
|
val (>=): t -> t -> bool
|
|
(** Same as [geq]. *)
|
|
|
|
val (<>): t -> t -> bool
|
|
(** [a <> b] is equivalent to [not (equal a b)]. *)
|
|
|
|
end
|
|
|
|
(** {1 Miscellaneous} *)
|
|
|
|
val version: string
|
|
(** Library version.
|
|
@since 1.1
|
|
*)
|
|
|
|
(**/**)
|
|
|
|
(** For internal use in module [Q]. *)
|
|
val round_to_float: t -> bool -> float
|