This commit is contained in:
parent
aa2ff7b2f0
commit
2f3113f55d
11742 changed files with 1223940 additions and 0 deletions
555
unikernel/duniverse/Zarith/z.ml
Normal file
555
unikernel/duniverse/Zarith/z.ml
Normal file
|
|
@ -0,0 +1,555 @@
|
|||
(**
|
||||
Integers.
|
||||
|
||||
|
||||
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).
|
||||
|
||||
*)
|
||||
|
||||
type t
|
||||
|
||||
exception Overflow
|
||||
|
||||
external init: unit -> unit = "ml_z_init"
|
||||
let _ = init ()
|
||||
|
||||
let _ = Callback.register_exception "ml_z_overflow" Overflow
|
||||
|
||||
external is_small_int: t -> bool = "%obj_is_int"
|
||||
external unsafe_to_int: t -> int = "%identity"
|
||||
external of_int: int -> t = "%identity"
|
||||
|
||||
external c_neg: t -> t = "ml_z_neg"
|
||||
|
||||
let neg x =
|
||||
if is_small_int x && unsafe_to_int x <> min_int
|
||||
then of_int (- unsafe_to_int x)
|
||||
else c_neg x
|
||||
|
||||
external c_add: t -> t -> t = "ml_z_add"
|
||||
|
||||
let add x y =
|
||||
if is_small_int x && is_small_int y then begin
|
||||
let z = unsafe_to_int x + unsafe_to_int y in
|
||||
(* Overflow check -- Hacker's Delight, section 2.12 *)
|
||||
if (z lxor unsafe_to_int x) land (z lxor unsafe_to_int y) >= 0
|
||||
then of_int z
|
||||
else c_add x y
|
||||
end else
|
||||
c_add x y
|
||||
|
||||
external c_sub: t -> t -> t = "ml_z_sub"
|
||||
|
||||
let sub x y =
|
||||
if is_small_int x && is_small_int y then begin
|
||||
let z = unsafe_to_int x - unsafe_to_int y in
|
||||
(* Overflow check -- Hacker's Delight, section 2.12 *)
|
||||
if (unsafe_to_int x lxor unsafe_to_int y)
|
||||
land (z lxor unsafe_to_int x) >= 0
|
||||
then of_int z
|
||||
else c_sub x y
|
||||
end else
|
||||
c_sub x y
|
||||
|
||||
external mul_overflows: int -> int -> bool = "ml_z_mul_overflows" [@@noalloc]
|
||||
external c_mul: t -> t -> t = "ml_z_mul"
|
||||
|
||||
let mul x y =
|
||||
if is_small_int x && is_small_int y
|
||||
&& not (mul_overflows (unsafe_to_int x) (unsafe_to_int y))
|
||||
then of_int (unsafe_to_int x * unsafe_to_int y)
|
||||
else c_mul x y
|
||||
|
||||
external c_div: t -> t -> t = "ml_z_div"
|
||||
|
||||
let div x y =
|
||||
if is_small_int y then
|
||||
if unsafe_to_int y = -1 then
|
||||
neg x
|
||||
else if is_small_int x then
|
||||
of_int (unsafe_to_int x / unsafe_to_int y)
|
||||
else
|
||||
c_div x y
|
||||
else
|
||||
c_div x y
|
||||
|
||||
external cdiv: t -> t -> t = "ml_z_cdiv"
|
||||
external fdiv: t -> t -> t = "ml_z_fdiv"
|
||||
|
||||
external c_rem: t -> t -> t = "ml_z_rem"
|
||||
|
||||
let rem x y =
|
||||
if is_small_int y then
|
||||
if unsafe_to_int y = -1 then
|
||||
of_int 0
|
||||
else if is_small_int x then
|
||||
of_int (unsafe_to_int x mod unsafe_to_int y)
|
||||
else
|
||||
c_rem x y
|
||||
else
|
||||
c_rem x y
|
||||
|
||||
external div_rem: t -> t -> (t * t) = "ml_z_div_rem"
|
||||
|
||||
external c_divexact: t -> t -> t = "ml_z_divexact"
|
||||
|
||||
let divexact x y =
|
||||
if is_small_int y then
|
||||
if unsafe_to_int y = -1 then
|
||||
neg x
|
||||
else if is_small_int x then
|
||||
of_int (unsafe_to_int x / unsafe_to_int y)
|
||||
else
|
||||
c_divexact x y
|
||||
else
|
||||
c_divexact x y
|
||||
|
||||
external c_succ: t -> t = "ml_z_succ"
|
||||
|
||||
let succ x =
|
||||
if is_small_int x && unsafe_to_int x <> max_int
|
||||
then of_int (unsafe_to_int x + 1)
|
||||
else c_succ x
|
||||
|
||||
external c_pred: t -> t = "ml_z_pred"
|
||||
|
||||
let pred x =
|
||||
if is_small_int x && unsafe_to_int x <> min_int
|
||||
then of_int (unsafe_to_int x - 1)
|
||||
else c_pred x
|
||||
|
||||
external c_abs: t -> t = "ml_z_abs"
|
||||
|
||||
let abs x =
|
||||
if is_small_int x then
|
||||
if unsafe_to_int x >= 0 then x
|
||||
else if unsafe_to_int x <> min_int then
|
||||
of_int (- unsafe_to_int x)
|
||||
else
|
||||
c_abs x
|
||||
else
|
||||
c_abs x
|
||||
|
||||
external c_logand: t -> t -> t = "ml_z_logand"
|
||||
|
||||
let logand x y =
|
||||
if is_small_int x && is_small_int y
|
||||
then of_int (unsafe_to_int x land unsafe_to_int y)
|
||||
else c_logand x y
|
||||
|
||||
external c_logor: t -> t -> t = "ml_z_logor"
|
||||
|
||||
let logor x y =
|
||||
if is_small_int x && is_small_int y
|
||||
then of_int (unsafe_to_int x lor unsafe_to_int y)
|
||||
else c_logor x y
|
||||
|
||||
external c_logxor: t -> t -> t = "ml_z_logxor"
|
||||
|
||||
let logxor x y =
|
||||
if is_small_int x && is_small_int y
|
||||
then of_int (unsafe_to_int x lxor unsafe_to_int y)
|
||||
else c_logxor x y
|
||||
|
||||
external c_lognot: t -> t = "ml_z_lognot"
|
||||
|
||||
let lognot x =
|
||||
if is_small_int x
|
||||
then of_int (unsafe_to_int x lxor (-1))
|
||||
else c_lognot x
|
||||
|
||||
external c_shift_left: t -> int -> t = "ml_z_shift_left"
|
||||
|
||||
let shift_left x y =
|
||||
if is_small_int x && y >= 0 && y < Sys.word_size then begin
|
||||
let z = unsafe_to_int x lsl y in
|
||||
if z asr y = unsafe_to_int x
|
||||
then of_int z
|
||||
else c_shift_left x y
|
||||
end else
|
||||
c_shift_left x y
|
||||
|
||||
external c_shift_right: t -> int -> t = "ml_z_shift_right"
|
||||
|
||||
let shift_right x y =
|
||||
if is_small_int x && y >= 0 then
|
||||
of_int
|
||||
(unsafe_to_int x asr (if y < Sys.word_size then y else Sys.word_size - 1))
|
||||
else
|
||||
c_shift_right x y
|
||||
|
||||
external c_shift_right_trunc: t -> int -> t = "ml_z_shift_right_trunc"
|
||||
|
||||
let shift_right_trunc x y =
|
||||
if is_small_int x && y >= 0 then
|
||||
if y >= Sys.word_size then
|
||||
of_int 0
|
||||
else if unsafe_to_int x >= 0 then
|
||||
of_int (unsafe_to_int x lsr y)
|
||||
else
|
||||
of_int (- ((- unsafe_to_int x) lsr y))
|
||||
else
|
||||
c_shift_right_trunc x y
|
||||
|
||||
external of_int32: int32 -> t = "ml_z_of_int32"
|
||||
external of_int64: int64 -> t = "ml_z_of_int64"
|
||||
external of_nativeint: nativeint -> t = "ml_z_of_nativeint"
|
||||
external of_float: float -> t = "ml_z_of_float"
|
||||
|
||||
let uint32_mask = pred (shift_left (of_int 1) 32)
|
||||
let of_int32_unsigned x = logand (of_int32 x) uint32_mask
|
||||
|
||||
let uint64_mask = pred (shift_left (of_int 1) 64)
|
||||
let of_int64_unsigned x = logand (of_int64 x) uint64_mask
|
||||
|
||||
let uintnat_mask = pred (shift_left (of_int 1) Nativeint.size)
|
||||
let of_nativeint_unsigned x = logand (of_nativeint x) uintnat_mask
|
||||
|
||||
external c_to_int: t -> int = "ml_z_to_int"
|
||||
|
||||
let to_int x =
|
||||
if is_small_int x then unsafe_to_int x else c_to_int x
|
||||
|
||||
external to_int32: t -> int32 = "ml_z_to_int32"
|
||||
external to_int64: t -> int64 = "ml_z_to_int64"
|
||||
external to_nativeint: t -> nativeint = "ml_z_to_nativeint"
|
||||
external to_int32_unsigned: t -> int32 = "ml_z_to_int32_unsigned"
|
||||
external to_int64_unsigned: t -> int64 = "ml_z_to_int64_unsigned"
|
||||
external to_nativeint_unsigned: t -> nativeint = "ml_z_to_nativeint_unsigned"
|
||||
external format: string -> t -> string = "ml_z_format"
|
||||
external of_substring_base: int -> string -> pos:int -> len:int -> t = "ml_z_of_substring_base"
|
||||
external compare: t -> t -> int = "ml_z_compare" [@@noalloc]
|
||||
external equal: t -> t -> bool = "ml_z_equal" [@@noalloc]
|
||||
external sign: t -> int = "ml_z_sign" [@@noalloc]
|
||||
external gcd: t -> t -> t = "ml_z_gcd"
|
||||
external gcdext_intern: t -> t -> (t * t * bool) = "ml_z_gcdext_intern"
|
||||
external sqrt: t -> t = "ml_z_sqrt"
|
||||
external sqrt_rem: t -> (t * t) = "ml_z_sqrt_rem"
|
||||
external numbits: t -> int = "ml_z_numbits" [@@noalloc]
|
||||
external trailing_zeros: t -> int = "ml_z_trailing_zeros" [@@noalloc]
|
||||
external popcount: t -> int = "ml_z_popcount"
|
||||
external hamdist: t -> t -> int = "ml_z_hamdist"
|
||||
external size: t -> int = "ml_z_size" [@@noalloc]
|
||||
external fits_int: t -> bool = "ml_z_fits_int" [@@noalloc]
|
||||
external fits_int32: t -> bool = "ml_z_fits_int32" [@@noalloc]
|
||||
external fits_int64: t -> bool = "ml_z_fits_int64" [@@noalloc]
|
||||
external fits_nativeint: t -> bool = "ml_z_fits_nativeint" [@@noalloc]
|
||||
external fits_int32_unsigned: t -> bool = "ml_z_fits_int32_unsigned" [@@noalloc]
|
||||
external fits_int64_unsigned: t -> bool = "ml_z_fits_int64_unsigned" [@@noalloc]
|
||||
external fits_nativeint_unsigned: t -> bool = "ml_z_fits_nativeint_unsigned" [@@noalloc]
|
||||
external extract: t -> int -> int -> t = "ml_z_extract"
|
||||
external powm: t -> t -> t -> t = "ml_z_powm"
|
||||
external pow: t -> int -> t = "ml_z_pow"
|
||||
external powm_sec: t -> t -> t -> t = "ml_z_powm_sec"
|
||||
external root: t -> int -> t = "ml_z_root"
|
||||
external rootrem: t -> int -> t * t = "ml_z_rootrem"
|
||||
external invert: t -> t -> t = "ml_z_invert"
|
||||
external perfect_power: t -> bool = "ml_z_perfect_power"
|
||||
external perfect_square: t -> bool = "ml_z_perfect_square"
|
||||
external probab_prime: t -> int -> int = "ml_z_probab_prime"
|
||||
external nextprime: t -> t = "ml_z_nextprime"
|
||||
let hash: t -> int = Stdlib.Hashtbl.hash
|
||||
let seeded_hash: int -> t -> int = Stdlib.Hashtbl.seeded_hash
|
||||
external to_bits: t -> string = "ml_z_to_bits"
|
||||
external of_bits: string -> t = "ml_z_of_bits"
|
||||
|
||||
external c_divisible: t -> t -> bool = "ml_z_divisible"
|
||||
|
||||
let divisible x y =
|
||||
if is_small_int x then
|
||||
if is_small_int y then
|
||||
if unsafe_to_int y = 0
|
||||
then unsafe_to_int x = 0
|
||||
else (unsafe_to_int x) mod (unsafe_to_int y) = 0
|
||||
else
|
||||
(* If y divides x, we have |y| <= |x| or x = 0.
|
||||
Here, x is small: min_int <= x <= max_int
|
||||
and y is not small: y < min_int \/ y > max_int.
|
||||
|y| <= |x| is possible only if
|
||||
x = min_int and y = -min_int = max_int+1 .
|
||||
So, the only two cases where y divides x are
|
||||
x = 0 or x = min_int /\ y = -min_int. *)
|
||||
unsafe_to_int x = 0 || (unsafe_to_int x = min_int && y = c_neg x)
|
||||
else
|
||||
c_divisible x y
|
||||
|
||||
external congruent: t -> t -> t -> bool = "ml_z_congruent"
|
||||
external jacobi: t -> t -> int = "ml_z_jacobi"
|
||||
external legendre: t -> t -> int = "ml_z_legendre"
|
||||
external kronecker: t -> t -> int = "ml_z_kronecker"
|
||||
external remove: t -> t -> t * int = "ml_z_remove"
|
||||
external fac: int -> t = "ml_z_fac"
|
||||
external fac2: int -> t = "ml_z_fac2"
|
||||
external facM: int -> int -> t = "ml_z_facM"
|
||||
external primorial: int -> t = "ml_z_primorial"
|
||||
external bin: t -> int -> t = "ml_z_bin"
|
||||
external fib: int -> t = "ml_z_fib"
|
||||
external lucnum: int -> t = "ml_z_lucnum"
|
||||
|
||||
let zero = of_int 0
|
||||
let one = of_int 1
|
||||
let minus_one = of_int (-1)
|
||||
|
||||
let min a b = if compare a b <= 0 then a else b
|
||||
let max a b = if compare a b >= 0 then a else b
|
||||
|
||||
let leq a b = compare a b <= 0
|
||||
let geq a b = compare a b >= 0
|
||||
let lt a b = compare a b < 0
|
||||
let gt a b = compare a b > 0
|
||||
|
||||
let to_string = format "%d"
|
||||
|
||||
let of_string s = of_substring_base 0 s ~pos:0 ~len:(String.length s)
|
||||
let of_substring = of_substring_base 0
|
||||
let of_string_base base s = of_substring_base base s ~pos:0 ~len:(String.length s)
|
||||
|
||||
let ediv_rem a b =
|
||||
(* we have a = q * b + r, but [Big_int]'s remainder satisfies 0 <= r < |b|,
|
||||
while [Z]'s remainder satisfies -|b| < r < |b| and sign(r) = sign(a)
|
||||
*)
|
||||
let q,r = div_rem a b in
|
||||
if sign r >= 0 then (q,r) else
|
||||
if sign b >= 0 then (pred q, add r b)
|
||||
else (succ q, sub r b)
|
||||
|
||||
let ediv a b =
|
||||
if sign b >= 0 then fdiv a b else cdiv a b
|
||||
|
||||
let erem a b =
|
||||
let r = rem a b in
|
||||
if sign r >= 0 then r else add r (abs b)
|
||||
|
||||
let gcdext u v =
|
||||
match sign u, sign v with
|
||||
(* special cases: one argument is null *)
|
||||
| 0, 0 -> zero, zero, zero
|
||||
| 0, 1 -> v, zero, one
|
||||
| 0, -1 -> neg v, zero, minus_one
|
||||
| 1, 0 -> u, one, zero
|
||||
| -1, 0 -> neg u, minus_one, zero
|
||||
| _ ->
|
||||
(* general case *)
|
||||
let g,s,z = gcdext_intern u v in
|
||||
if z then g, s, div (sub g (mul u s)) v
|
||||
else g, div (sub g (mul v s)) u, s
|
||||
|
||||
let lcm u v =
|
||||
if u = zero || v = zero then zero
|
||||
else
|
||||
let g = gcd u v in
|
||||
abs (mul (divexact u g) v)
|
||||
|
||||
external testbit_internal: t -> int -> bool = "ml_z_testbit" [@@noalloc]
|
||||
let testbit x n =
|
||||
if n >= 0 then testbit_internal x n else invalid_arg "Z.testbit"
|
||||
(* The test [n >= 0] is done in Caml rather than in the C stub code
|
||||
so that the latter raises no exceptions and can be declared [@@noalloc]. *)
|
||||
|
||||
let is_odd x = testbit_internal x 0
|
||||
let is_even x = not (testbit_internal x 0)
|
||||
|
||||
external c_extract_small: t -> int -> int -> t
|
||||
= "ml_z_extract_small" [@@noalloc]
|
||||
external c_extract: t -> int -> int -> t = "ml_z_extract"
|
||||
|
||||
let extract_internal x o l =
|
||||
if is_small_int x then
|
||||
(* Fast path *)
|
||||
let o = if o >= Sys.int_size then Sys.int_size - 1 else o in
|
||||
(* Shift away low "o" bits. If "o" too big, just replicate sign bit. *)
|
||||
let z = unsafe_to_int x asr o in
|
||||
if l < Sys.int_size then
|
||||
(* Extract "l" low bits, if "l" is small enough *)
|
||||
of_int (z land ((1 lsl l) - 1))
|
||||
else if z >= 0 then
|
||||
(* If x >= 0, the extraction of "l" low bits keeps x unchanged. *)
|
||||
of_int z
|
||||
else
|
||||
(* If x < 0, fall through slow path *)
|
||||
c_extract x o l
|
||||
else if l < Sys.int_size then
|
||||
(* Alternative fast path since no allocation is required *)
|
||||
c_extract_small x o l
|
||||
else
|
||||
c_extract x o l
|
||||
|
||||
let extract x o l =
|
||||
if o < 0 then invalid_arg "Z.extract: negative bit offset";
|
||||
if l < 1 then invalid_arg "Z.extract: nonpositive bit length";
|
||||
extract_internal x o l
|
||||
|
||||
let signed_extract x o l =
|
||||
if o < 0 then invalid_arg "Z.signed_extract: negative bit offset";
|
||||
if l < 1 then invalid_arg "Z.signed_extract: nonpositive bit length";
|
||||
if testbit x (o + l - 1)
|
||||
then lognot (extract (lognot x) o l)
|
||||
else extract x o l
|
||||
|
||||
let log2 x =
|
||||
if sign x > 0 then (numbits x) - 1 else invalid_arg "Z.log2"
|
||||
let log2up x =
|
||||
if sign x > 0 then numbits (pred x) else invalid_arg "Z.log2up"
|
||||
|
||||
(* Consider a real number [r] such that
|
||||
- the integral part of [r] is the bigint [x]
|
||||
- 2^54 <= |x| < 2^63
|
||||
- the fractional part of [r] is 0 if [exact = true],
|
||||
nonzero if [exact = false].
|
||||
Then, the following function returns [r] correctly rounded
|
||||
according to the current rounding mode of the processor.
|
||||
This is an instance of the "round to odd" technique formalized in
|
||||
"When double rounding is odd" by S. Boldo and G. Melquiond.
|
||||
The claim above is lemma Fappli_IEEE_extra.round_odd_fix
|
||||
from the CompCert Coq development. *)
|
||||
|
||||
let round_to_float x exact =
|
||||
let m = to_int64 x in
|
||||
(* Unless the fractional part is exactly 0, round m to an odd integer *)
|
||||
let m = if exact then m else Int64.logor m 1L in
|
||||
(* Then convert m to float, with the current rounding mode. *)
|
||||
Int64.to_float m
|
||||
|
||||
let to_float x =
|
||||
if Obj.is_int (Obj.repr x) then
|
||||
(* Fast path *)
|
||||
float_of_int (Obj.magic x : int)
|
||||
else begin
|
||||
let n = numbits x in
|
||||
if n <= 63 then
|
||||
Int64.to_float (to_int64 x)
|
||||
else begin
|
||||
let n = n - 55 in
|
||||
(* Extract top 55 bits of x *)
|
||||
let top = shift_right x n in
|
||||
(* Check if the other bits are all zero *)
|
||||
let exact = equal x (shift_left top n) in
|
||||
(* Round to float and apply exponent *)
|
||||
ldexp (round_to_float top exact) n
|
||||
end
|
||||
end
|
||||
|
||||
(* Formatting *)
|
||||
|
||||
let print x = print_string (to_string x)
|
||||
let output chan x = output_string chan (to_string x)
|
||||
let sprint () x = to_string x
|
||||
let bprint b x = Buffer.add_string b (to_string x)
|
||||
let pp_print f x = Format.pp_print_string f (to_string x)
|
||||
|
||||
(* Pseudo-random generation *)
|
||||
|
||||
let rec raw_bits_random ?(rng: Random.State.t option) nbits =
|
||||
let rec raw_bits accu n =
|
||||
if n >= nbits then (accu, n) else begin
|
||||
let i =
|
||||
match rng with
|
||||
| None -> Random.bits ()
|
||||
| Some r -> Random.State.bits r in
|
||||
raw_bits (logxor (shift_left accu 30) (of_int i)) (n + 30)
|
||||
end in
|
||||
raw_bits zero 0
|
||||
|
||||
let raw_bits_from_bytes ~(fill: bytes -> int -> int -> unit) nbits =
|
||||
let nbytes = (nbits + 7) / 8 in
|
||||
let buf = Bytes.create nbytes in
|
||||
fill buf 0 nbytes;
|
||||
(of_bits (Bytes.to_string buf), nbytes * 8)
|
||||
|
||||
let random_bits_aux (f: int -> t * int) nbits =
|
||||
if nbits < 0 then invalid_arg "random_bits: number of bits must be >= 0";
|
||||
let (x, _) = f nbits in
|
||||
extract x 0 nbits
|
||||
|
||||
let random_int_aux (f: int -> t * int) bound =
|
||||
if sign bound <= 0 then invalid_arg "random_int: bound must be > 0";
|
||||
let nbits1 = log2up bound in
|
||||
let rec draw () =
|
||||
(* The minimal number of random bits we need to draw is nbits1.
|
||||
However, in the worst case, rejection (as described below)
|
||||
will occur with probability almost 1/2. So, we draw more bits
|
||||
than strictly necessary to make rejection much less likely.
|
||||
With 4 extra bits, the probability of rejection is less than
|
||||
1/32. *)
|
||||
let (x, nbits) = f (nbits1 + 4) in
|
||||
let y = rem x bound in
|
||||
(* We divide the range of x, namely [0 .. 2^nbits), into
|
||||
- k intervals of width bound :
|
||||
[0 .. bound) [bound.. 2*bound) .. [(k-1) * bound.. k * bound)
|
||||
- the remaining numbers: [k * bound .. 2^nbits)
|
||||
|
||||
k is chosen as large as possible: k = floor (2^nbits / bound).
|
||||
|
||||
If x falls within the k intervals of width bound,
|
||||
y = x mod bound is evenly distributed in [0 .. bound)
|
||||
and we can use it as the pseudo-random number.
|
||||
If x falls within the [k * bound .. 2^nbits) interval,
|
||||
y = x mod bound may not be evenly distributed;
|
||||
we reject and draw again.
|
||||
|
||||
We can decide efficiently whether to reject, as follows.
|
||||
Write 2^nbits = k * bound + r and x = q * bound + y,
|
||||
with r and y in [0 .. bound).
|
||||
If x - y <= 2^nbits - bound, then
|
||||
q * bound = x - y <= 2^nbits - bound < 2^nbits - r = k * bound,
|
||||
hence q < k and we can accept x.
|
||||
Otherwise,
|
||||
q * bound = x - y > 2^nbits - bound = (k - 1) * bound + r
|
||||
hence q >= k and we must reject x.
|
||||
*)
|
||||
if leq (sub x y) (sub (shift_left one nbits) bound)
|
||||
then y
|
||||
else draw () in
|
||||
draw ()
|
||||
|
||||
let random_int ?rng bound =
|
||||
random_int_aux (raw_bits_random ?rng) bound
|
||||
let random_bits ?rng nbits =
|
||||
random_bits_aux (raw_bits_random ?rng) nbits
|
||||
|
||||
let random_int_gen ~fill bound =
|
||||
random_int_aux (raw_bits_from_bytes ~fill) bound
|
||||
let random_bits_gen ~fill nbits =
|
||||
random_bits_aux (raw_bits_from_bytes ~fill) nbits
|
||||
|
||||
(* Infix notations *)
|
||||
|
||||
let (~-) = neg
|
||||
let (~+) x = x
|
||||
let (+) = add
|
||||
let (-) = sub
|
||||
let ( * ) = mul
|
||||
let (/) = div
|
||||
external (/>): t -> t -> t = "ml_z_cdiv"
|
||||
external (/<): t -> t -> t = "ml_z_fdiv"
|
||||
let (/|) = divexact
|
||||
let (mod) = rem
|
||||
let (land) = logand
|
||||
let (lor) = logor
|
||||
let (lxor) = logxor
|
||||
let (~!) = lognot
|
||||
let (lsl) = shift_left
|
||||
let (asr) = shift_right
|
||||
external (~$): int -> t = "%identity"
|
||||
external ( ** ): t -> int -> t = "ml_z_pow"
|
||||
|
||||
module Compare = struct
|
||||
let (=) = equal
|
||||
let (<) = lt
|
||||
let (>) = gt
|
||||
let (<=) = leq
|
||||
let (>=) = geq
|
||||
let (<>) a b = not (equal a b)
|
||||
end
|
||||
|
||||
let version = Zarith_version.version
|
||||
Loading…
Add table
Add a link
Reference in a new issue