mte/unikernel/duniverse/Zarith/z.mli

881 lines
27 KiB
OCaml
Raw Normal View History

2025-11-11 02:07:51 +01:00
(**
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