mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 03:05:28 -05:00
Merge pull request #308 from FardaleM/ccint
CCInt{,32,64} and CCNativeint
This commit is contained in:
commit
685efeae28
10 changed files with 1212 additions and 394 deletions
|
|
@ -3,9 +3,35 @@
|
|||
|
||||
open CCShims_
|
||||
|
||||
include CCShimsInt_
|
||||
|
||||
type t = int
|
||||
type 'a iter = ('a -> unit) -> unit
|
||||
|
||||
let zero = 0
|
||||
|
||||
let one = 1
|
||||
|
||||
let minus_one = -1
|
||||
|
||||
let add = (+)
|
||||
|
||||
let sub = (-)
|
||||
|
||||
let mul = ( * )
|
||||
|
||||
let div = (/)
|
||||
|
||||
let succ = succ
|
||||
|
||||
let pred = pred
|
||||
|
||||
let abs = abs
|
||||
|
||||
let max_int = max_int
|
||||
|
||||
let min_int = min_int
|
||||
|
||||
let equal (a:int) b = Stdlib.(=) a b
|
||||
|
||||
let compare (a:int) b = compare a b
|
||||
|
|
@ -45,10 +71,7 @@ let range' i j yield =
|
|||
[5;4;3] (range' 5 2 |> Iter.to_list)
|
||||
*)
|
||||
|
||||
let sign i =
|
||||
if i < 0 then -1
|
||||
else if i>0 then 1
|
||||
else 0
|
||||
let sign i = compare i 0
|
||||
|
||||
let neg i = -i
|
||||
|
||||
|
|
@ -211,6 +234,8 @@ let of_string s =
|
|||
|
||||
let of_string_exn = Stdlib.int_of_string
|
||||
|
||||
let to_float = float_of_int
|
||||
|
||||
let of_float = int_of_float
|
||||
|
||||
(*$=
|
||||
|
|
@ -267,7 +292,7 @@ let range_by ~step i j yield =
|
|||
)
|
||||
in
|
||||
if step = 0 then
|
||||
raise (Invalid_argument "CCList.range_by")
|
||||
raise (Invalid_argument "CCInt.range_by")
|
||||
else if (if step > 0 then i>j else i<j) then ()
|
||||
else range i ((j-i)/step*step + i) yield
|
||||
|
||||
|
|
@ -359,3 +384,17 @@ let popcount (b:int) : int =
|
|||
);
|
||||
true)
|
||||
*)
|
||||
|
||||
let logand = (land)
|
||||
|
||||
let logor = (lor)
|
||||
|
||||
let logxor = (lxor)
|
||||
|
||||
let lognot = lnot
|
||||
|
||||
let shift_left = (lsl)
|
||||
|
||||
let shift_right = (asr)
|
||||
|
||||
let shift_right_logical = (lsr)
|
||||
|
|
|
|||
|
|
@ -3,10 +3,61 @@
|
|||
|
||||
(** {1 Basic Int functions} *)
|
||||
|
||||
include module type of CCShimsInt_
|
||||
|
||||
type t = int
|
||||
|
||||
val zero : t
|
||||
(** [zero] is the integer [0].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val one : t
|
||||
(** [one] is the integer [1].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val minus_one : t
|
||||
(** [minus_one] is the integer [-1].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val add : t -> t -> t
|
||||
(** [add x y] is [x + y].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val sub : t -> t -> t
|
||||
(** [sub x y] is [x - y].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val mul : t -> t -> t
|
||||
(** [mul x y] is [x * y].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val div : t -> t -> t
|
||||
(** [div x y] is [x / y]
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val succ : t -> t
|
||||
(** [succ x] is [x + 1].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val pred : t -> t
|
||||
(** [pred x] is [x - 1].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val abs : t -> t
|
||||
(** [abs x] is the absolute value of [x]. It is [x] if [x] is positive
|
||||
and [neg x] otherwise.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val max_int : t
|
||||
(** [max_int] is the maximum integer.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val min_int : t
|
||||
(** [min_int] is the minimum integer.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val compare : t -> t -> int
|
||||
(** [compare x y] is the comparison function for integers
|
||||
(** [compare x y] is the comparison function for integers
|
||||
with the same specification as {!Stdlib.compare}. *)
|
||||
|
||||
val equal : t -> t -> bool
|
||||
|
|
@ -15,9 +66,10 @@ val equal : t -> t -> bool
|
|||
|
||||
val hash : t -> int
|
||||
(** [hash x] computes the hash of [x]. *)
|
||||
|
||||
|
||||
val sign : t -> int
|
||||
(** [sign x] is one of [-1, 0, 1]. *)
|
||||
(** [sign x] return [0] if [x = 0], [-1] if [x < 0] and [1] if [x > 0].
|
||||
Same as [compare x 0].*)
|
||||
|
||||
val neg : t -> t
|
||||
(** [neg x] is [- x].
|
||||
|
|
@ -49,7 +101,15 @@ val random_small : t random_gen
|
|||
val random_range : int -> int -> t random_gen
|
||||
|
||||
val pp : t printer
|
||||
(** [pp ppf x] prints the integer [x] on [ppf]. *)
|
||||
(** [pp ppf x] prints the integer [x] on [ppf]. *)
|
||||
|
||||
val to_float : t -> float
|
||||
(** [to_float] is the same as [float_of_int]
|
||||
@since NEXT_RELEASE*)
|
||||
|
||||
val of_float : float -> t
|
||||
(** [to_float] is the same as [int_of_float]
|
||||
@since NEXT_RELEASE*)
|
||||
|
||||
val to_string : t -> string
|
||||
(** [to_string x] returns the string representation of the integer [x], in signed decimal.
|
||||
|
|
@ -109,6 +169,34 @@ val popcount : t -> int
|
|||
(** Number of bits set to 1
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val logand : t -> t -> t
|
||||
(** [logand] is the same as [(land)].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val logor : t -> t -> t
|
||||
(** [logand] is the same as [(lor)].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val logxor : t -> t -> t
|
||||
(** [logxor] is the same as [(lxor)].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val lognot : t -> t
|
||||
(** [logand] is the same as [lnot].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val shift_left : t -> int -> t
|
||||
(** [shift_left] is the same as [(lsl)].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val shift_right : t -> int -> t
|
||||
(** [shift_right] is the same as [(asr)].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val shift_right_logical : t -> int -> t
|
||||
(** [shift_right_logical] is the same as [(lsr)].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
(** {2 Infix Operators}
|
||||
|
||||
@since 0.17 *)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,200 @@
|
|||
open CCShims_
|
||||
include Int32
|
||||
|
||||
|
||||
let min : t -> t -> t = Stdlib.min
|
||||
let max : t -> t -> t = Stdlib.max
|
||||
|
||||
let hash x = Stdlib.abs (to_int x)
|
||||
|
||||
let sign i = compare i zero
|
||||
|
||||
let pow a b =
|
||||
let rec aux acc = function
|
||||
| 1l -> acc
|
||||
| n ->
|
||||
if equal (rem n 2l) zero
|
||||
then aux (mul acc acc) (div n 2l)
|
||||
else mul acc (aux (mul acc acc) (div n 2l))
|
||||
in
|
||||
match b with
|
||||
| 0l -> if equal a 0l then raise (Invalid_argument "pow: undefined value 0^0") else 1l
|
||||
| b when compare b 0l < 0 -> raise (Invalid_argument "pow: can't raise int to negative power")
|
||||
| b -> aux a b
|
||||
|
||||
(*$T
|
||||
pow 2l 10l = 1024l
|
||||
pow 2l 15l = 32768l
|
||||
pow 10l 5l = 100000l
|
||||
pow 42l 0l = 1l
|
||||
pow 0l 1l = 0l
|
||||
*)
|
||||
|
||||
let floor_div a n =
|
||||
if compare a 0l < 0 && compare n 0l >= 0 then
|
||||
sub (div (add a 1l) n) 1l
|
||||
else if compare a 0l > 0 && compare n 0l < 0 then
|
||||
sub (div (sub a 1l) n) 1l
|
||||
else
|
||||
div a n
|
||||
|
||||
(*$T
|
||||
(floor_div 3l 5l = 0l)
|
||||
(floor_div 5l 5l = 1l)
|
||||
(floor_div 20l 5l = 4l)
|
||||
(floor_div 12l 5l = 2l)
|
||||
(floor_div 0l 5l = 0l)
|
||||
(floor_div (-1l) 5l = -1l)
|
||||
(floor_div (-5l) 5l = -1l)
|
||||
(floor_div (-12l) 5l = -3l)
|
||||
|
||||
(floor_div 0l (-5l) = 0l)
|
||||
(floor_div 3l (-5l) = -1l)
|
||||
(floor_div 5l (-5l) = -1l)
|
||||
(floor_div 9l (-5l) = -2l)
|
||||
(floor_div 20l (-5l) = -4l)
|
||||
(floor_div (-2l) (-5l) = 0l)
|
||||
(floor_div (-8l) (-5l) = 1l)
|
||||
(floor_div (-35l) (-5l) = 7l)
|
||||
|
||||
try ignore (floor_div 12l 0l); false with Division_by_zero -> true
|
||||
try ignore (floor_div (-12l) 0l); false with Division_by_zero -> true
|
||||
*)
|
||||
|
||||
(*$Q
|
||||
(Q.pair (Q.map of_int Q.small_signed_int) (Q.map of_int Q.small_nat)) \
|
||||
(fun (n, m) -> let m = m + 1l in \
|
||||
floor_div n m = of_float @@ floor (to_float n /. to_float m))
|
||||
(Q.pair (Q.map of_int Q.small_signed_int) (Q.map of_int Q.small_nat)) \
|
||||
(fun (n, m) -> let m = m + 1l in \
|
||||
floor_div n (-m) = of_float @@ floor (to_float n /. to_float (-m)))
|
||||
*)
|
||||
|
||||
type 'a printer = Format.formatter -> 'a -> unit
|
||||
type 'a random_gen = Random.State.t -> 'a
|
||||
type 'a iter = ('a -> unit) -> unit
|
||||
|
||||
let range i j yield =
|
||||
let rec up i j yield =
|
||||
if equal i j then yield i
|
||||
else (
|
||||
yield i;
|
||||
up (add i 1l) j yield
|
||||
)
|
||||
and down i j yield =
|
||||
if equal i j then yield i
|
||||
else (
|
||||
yield i;
|
||||
down (sub i 1l) j yield
|
||||
)
|
||||
in
|
||||
if compare i j <= 0 then up i j yield else down i j yield
|
||||
|
||||
(*$= & ~printer:Q.Print.(list to_string)
|
||||
[0l;1l;2l;3l;4l;5l] (range 0l 5l |> Iter.to_list)
|
||||
[0l] (range 0l 0l |> Iter.to_list)
|
||||
[5l;4l;3l;2l] (range 5l 2l |> Iter.to_list)
|
||||
*)
|
||||
|
||||
let range' i j yield =
|
||||
if compare i j < 0 then range i (sub j 1l) yield
|
||||
else if equal i j then ()
|
||||
else range i (add j 1l) yield
|
||||
|
||||
let range_by ~step i j yield =
|
||||
let rec range i j yield =
|
||||
if equal i j then yield i
|
||||
else (
|
||||
yield i;
|
||||
range (add i step) j yield
|
||||
)
|
||||
in
|
||||
if equal step 0l then
|
||||
raise (Invalid_argument "CCInt32.range_by")
|
||||
else if (if compare step 0l > 0 then compare i j > 0 else compare i j < 0) then ()
|
||||
else range i (add (mul (div (sub j i) step) step) i) yield
|
||||
|
||||
(* note: the last test checks that no error occurs due to overflows. *)
|
||||
(*$= & ~printer:Q.Print.(list to_string)
|
||||
[0l] (range_by ~step:1l 0l 0l |> Iter.to_list)
|
||||
[] (range_by ~step:1l 5l 0l |> Iter.to_list)
|
||||
[] (range_by ~step:2l 1l 0l |> Iter.to_list)
|
||||
[0l;2l;4l] (range_by ~step:2l 0l 4l |> Iter.to_list)
|
||||
[0l;2l;4l] (range_by ~step:2l 0l 5l |> Iter.to_list)
|
||||
[0l] (range_by ~step:(neg 1l) 0l 0l |> Iter.to_list)
|
||||
[] (range_by ~step:(neg 1l) 0l 5l |> Iter.to_list)
|
||||
[] (range_by ~step:(neg 2l) 0l 1l |> Iter.to_list)
|
||||
[5l;3l;1l] (range_by ~step:(neg 2l) 5l 1l |> Iter.to_list)
|
||||
[5l;3l;1l] (range_by ~step:(neg 2l) 5l 0l |> Iter.to_list)
|
||||
[0l] (range_by ~step:max_int 0l 2l |> Iter.to_list)
|
||||
*)
|
||||
|
||||
(*$Q
|
||||
Q.(pair (map of_int small_int) (map of_int small_int)) (fun (i,j) -> \
|
||||
let i = min i j and j = max i j in \
|
||||
CCList.equal CCInt32.equal \
|
||||
(CCInt32.range_by ~step:1l i j |> Iter.to_list) \
|
||||
(CCInt32.range i j |> Iter.to_list) )
|
||||
*)
|
||||
|
||||
let random n st = Random.State.int32 st n
|
||||
let random_small = random 100l
|
||||
let random_range i j st = add i (random (sub j i) st)
|
||||
|
||||
|
||||
(** {2 Conversion} *)
|
||||
|
||||
let of_string_exn = of_string
|
||||
|
||||
let of_string x = try Some (of_string_exn x) with Failure _ -> None
|
||||
let of_string_opt = of_string
|
||||
|
||||
let most_significant_bit =
|
||||
logxor (neg 1l) (shift_right_logical (neg 1l) 1)
|
||||
|
||||
type output = char -> unit
|
||||
|
||||
(* abstract printer *)
|
||||
let to_binary_gen (out:output) n =
|
||||
let n = if compare n 0l <0 then (out '-'; neg n) else n in
|
||||
out '0'; out 'b';
|
||||
let rec loop started bit n =
|
||||
if equal bit 0l then (
|
||||
if not started then out '0'
|
||||
) else (
|
||||
let b = logand n bit in
|
||||
if equal b 0l then (
|
||||
if started then out '0';
|
||||
loop started (shift_right_logical bit 1) n
|
||||
) else (
|
||||
out '1';
|
||||
loop true (shift_right_logical bit 1) n
|
||||
)
|
||||
)
|
||||
in
|
||||
loop false most_significant_bit n
|
||||
|
||||
let to_string_binary n =
|
||||
let buf = Buffer.create 16 in
|
||||
to_binary_gen (Buffer.add_char buf) n;
|
||||
Buffer.contents buf
|
||||
|
||||
(*$= & ~printer:CCFun.id
|
||||
"0b111" (to_string_binary 7l)
|
||||
"-0b111" (to_string_binary (-7l))
|
||||
"0b0" (to_string_binary 0l)
|
||||
*)
|
||||
|
||||
(** {2 Printing} *)
|
||||
|
||||
let pp out n = Format.pp_print_string out (to_string n)
|
||||
|
||||
let pp_binary out n =
|
||||
to_binary_gen (Format.pp_print_char out) n
|
||||
|
||||
|
||||
(** {2 Infix Operators} *)
|
||||
|
||||
module Infix = struct
|
||||
let (+) = add
|
||||
|
||||
|
|
@ -14,6 +208,12 @@ module Infix = struct
|
|||
|
||||
let (/) = div
|
||||
|
||||
let ( ** ) = pow
|
||||
|
||||
let (--) = range
|
||||
|
||||
let (--^) = range'
|
||||
|
||||
let (mod) = rem
|
||||
|
||||
let (land) = logand
|
||||
|
|
@ -39,12 +239,3 @@ module Infix = struct
|
|||
let (>=) = Stdlib.(>=)
|
||||
end
|
||||
include Infix
|
||||
|
||||
let hash x = Stdlib.abs (to_int x)
|
||||
|
||||
(** {2 Conversion} *)
|
||||
|
||||
let of_string_exn = of_string
|
||||
|
||||
let of_string x = try Some (of_string_exn x) with Failure _ -> None
|
||||
let of_string_opt = of_string
|
||||
|
|
|
|||
|
|
@ -17,116 +17,69 @@
|
|||
|
||||
include module type of struct include Int32 end
|
||||
|
||||
val ( + ) : t -> t -> t
|
||||
(** [x + y] is the sum of [x] and [y].
|
||||
Addition. *)
|
||||
val min : t -> t -> t
|
||||
(** [min x y] returns the minimum of the two integers [x] and [y].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val ( - ) : t -> t -> t
|
||||
(** [x - y] is the difference of [x] and [y].
|
||||
Subtraction. *)
|
||||
|
||||
val ( ~- ) : t -> t
|
||||
(** [~- x] is the negation of [x].
|
||||
Unary negation. *)
|
||||
|
||||
val ( * ) : t -> t -> t
|
||||
(** [ x * y] is the product of [x] and [y].
|
||||
Multiplication. *)
|
||||
|
||||
val ( / ) : t -> t -> t
|
||||
(** [x / y] is the integer quotient of [x] and [y].
|
||||
Integer division. Raise [Division_by_zero] if the second
|
||||
argument [y] is zero. This division rounds the real quotient of
|
||||
its arguments towards zero, as specified for {!Stdlib.(/)}. *)
|
||||
|
||||
val ( mod ) : t -> t -> t
|
||||
(** [x mod y] is the integer remainder of [x / y].
|
||||
If [y <> zero], the result of [x mod y] satisfies the following property:
|
||||
[x = ((x / y) * y) + (x mod y)].
|
||||
If [y = 0], [x mod y] raises [Division_by_zero]. *)
|
||||
|
||||
val ( land ) : t -> t -> t
|
||||
(** [x land y] is the bitwise logical and of [x] and [y]. *)
|
||||
|
||||
val ( lor ) : t -> t -> t
|
||||
(** [x lor y] is the bitwise logical or of [x] and [y]. *)
|
||||
|
||||
val ( lxor ) : t -> t -> t
|
||||
(** [x lxor y] is the bitwise logical exclusive or of [x] and [y]. *)
|
||||
|
||||
val lnot : t -> t
|
||||
(** [lnot x] is the bitwise logical negation of [x] (the bits of [x] are inverted). *)
|
||||
|
||||
val ( lsl ) : t -> int -> t
|
||||
(** [ x lsl y] shifts [x] to the left by [y] bits, filling in with zeroes.
|
||||
The result is unspecified if [y < 0] or [y >= 32]. *)
|
||||
|
||||
val ( lsr ) : t -> int -> t
|
||||
(** [x lsr y] shifts [x] to the right by [y] bits.
|
||||
This is a logical shift: zeroes are inserted in the vacated bits
|
||||
regardless of the sign of [x].
|
||||
The result is unspecified if [y < 0] or [y >= 32]. *)
|
||||
|
||||
val ( asr ) : t -> int -> t
|
||||
(** [x asr y] shifts [x] to the right by [y] bits.
|
||||
This is an arithmetic shift: the sign bit of [x] is replicated
|
||||
and inserted in the vacated bits.
|
||||
The result is unspecified if [y < 0] or [y >= 32]. *)
|
||||
|
||||
module Infix : sig
|
||||
val (+) : t -> t -> t
|
||||
val (-) : t -> t -> t
|
||||
val (~-) : t -> t
|
||||
val ( * ) : t -> t -> t
|
||||
val (/) : t -> t -> t
|
||||
val (mod) : t -> t -> t
|
||||
val (land) : t -> t -> t
|
||||
val (lor) : t -> t -> t
|
||||
val (lxor) : t -> t -> t
|
||||
val lnot : t -> t
|
||||
val (lsl) : t -> int -> t
|
||||
val (lsr) : t -> int -> t
|
||||
val (asr) : t -> int -> t
|
||||
val (=) : t -> t -> bool
|
||||
val (<>) : t -> t -> bool
|
||||
val (>) : t -> t -> bool
|
||||
val (>=) : t -> t -> bool
|
||||
val (<=) : t -> t -> bool
|
||||
val (<) : t -> t -> bool
|
||||
end
|
||||
|
||||
include module type of Infix
|
||||
val max : t -> t -> t
|
||||
(** [max x y] returns the maximum of the two integers [x] and [y].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val hash : t -> int
|
||||
(** [hash x] computes the hash of [x].
|
||||
Like {!Stdlib.abs (to_int x)}. *)
|
||||
|
||||
val sign : t -> int
|
||||
(** [sign x] return [0] if [x = 0], [-1] if [x < 0] and [1] if [x > 0].
|
||||
Same as [compare x zero].
|
||||
@since NEXT_RELEASE*)
|
||||
|
||||
val pow : t -> t -> t
|
||||
(** [pow base exponent] returns [base] raised to the power of [exponent].
|
||||
[pow x y = x^y] for positive integers [x] and [y].
|
||||
Raises [Invalid_argument] if [x = y = 0] or [y] < 0.
|
||||
@since 0.11 *)
|
||||
|
||||
val floor_div : t -> t -> t
|
||||
(** [floor_div x n] is integer division rounding towards negative infinity.
|
||||
It satisfies [x = m * floor_div x n + rem x n].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
type 'a printer = Format.formatter -> 'a -> unit
|
||||
type 'a random_gen = Random.State.t -> 'a
|
||||
type 'a iter = ('a -> unit) -> unit
|
||||
|
||||
|
||||
val range_by : step:t -> t -> t -> t iter
|
||||
(** [range_by ~step i j] iterates on integers from [i] to [j] included,
|
||||
where the difference between successive elements is [step].
|
||||
Use a negative [step] for a decreasing list.
|
||||
@raise Invalid_argument if [step=0].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val range : t -> t -> t iter
|
||||
(** [range i j] iterates on integers from [i] to [j] included . It works
|
||||
both for decreasing and increasing ranges.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val range' : t -> t -> t iter
|
||||
(** [range' i j] is like {!range} but the second bound [j] is excluded.
|
||||
For instance [range' 0 5 = Iter.of_list [0;1;2;3;4]].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val random : t -> t random_gen
|
||||
val random_small : t random_gen
|
||||
val random_range : t -> t -> t random_gen
|
||||
|
||||
|
||||
(** {2 Conversion} *)
|
||||
|
||||
val to_int : t -> int
|
||||
(** [to_int x] converts the given 32-bit integer [x] (type [int32]) into an
|
||||
integer (type [int]). On 32-bit platforms, the 32-bit integer
|
||||
is taken modulo 2{^31}, i.e. the high-order bit is lost
|
||||
during the conversion. On 64-bit platforms, the conversion is exact. *)
|
||||
val of_string : string -> t option
|
||||
(** [of_string s] is the safe version of {!of_string_exn}.
|
||||
Like {!of_string_exn}, but return [None] instead of raising. *)
|
||||
|
||||
val of_int : int -> t
|
||||
(** [of_int x] converts the given integer [x] (type [int]) into an
|
||||
32-bit integer (type [int32]).
|
||||
Alias to {!Int32.of_int}. *)
|
||||
|
||||
val to_float : t -> float
|
||||
(** [to_float x] converts the given 32-bit integer [x]
|
||||
into a floating-point number (type [float]). *)
|
||||
|
||||
val of_float : float -> t
|
||||
(** [of_float x] converts the given floating-point number [x] into a 32-bit integer,
|
||||
discarding the fractional part (truncate towards 0).
|
||||
The result of the conversion is undefined if, after truncation, the number
|
||||
is outside the range \[{!CCInt32.min_int}, {!CCInt32.max_int}\].
|
||||
Alias to {!Int32.of_float}. *)
|
||||
|
||||
val to_string : t -> string
|
||||
(** [to_string x] returns the string representation of its argument [x], in signed decimal. *)
|
||||
val of_string_opt : string -> t option
|
||||
(** [of_string_opt s] is an alias to {!of_string}. *)
|
||||
|
||||
val of_string_exn : string -> t
|
||||
(** [of_string_exn s] converts the given string [s] into a 32-bit integer.
|
||||
|
|
@ -146,9 +99,101 @@ val of_string_exn : string -> t
|
|||
a valid representation of an integer, or if the integer represented
|
||||
exceeds the range of integers representable in type [int32]. *)
|
||||
|
||||
val of_string : string -> t option
|
||||
(** [of_string s] is the safe version of {!of_string_exn}.
|
||||
Like {!of_string_exn}, but return [None] instead of raising. *)
|
||||
val to_string_binary : t -> string
|
||||
(** [to_string_binary x] returns the string representation of the integer [x], in binary.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val of_string_opt : string -> t option
|
||||
(** [of_string_opt s] is an alias to {!of_string}. *)
|
||||
|
||||
(** {2 Printing} *)
|
||||
|
||||
val pp : t printer
|
||||
(** [pp ppf x] prints the integer [x] on [ppf].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val pp_binary : t printer
|
||||
(** [pp_binary ppf x] prints [x] on [ppf].
|
||||
Print as "0b00101010".
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
|
||||
(** {2 Infix Operators} *)
|
||||
|
||||
module Infix : sig
|
||||
val ( + ) : t -> t -> t
|
||||
(** [x + y] is the sum of [x] and [y].
|
||||
Addition. *)
|
||||
|
||||
val ( - ) : t -> t -> t
|
||||
(** [x - y] is the difference of [x] and [y].
|
||||
Subtraction. *)
|
||||
|
||||
val ( ~- ) : t -> t
|
||||
(** [~- x] is the negation of [x].
|
||||
Unary negation. *)
|
||||
|
||||
val ( * ) : t -> t -> t
|
||||
(** [ x * y] is the product of [x] and [y].
|
||||
Multiplication. *)
|
||||
|
||||
val ( / ) : t -> t -> t
|
||||
(** [x / y] is the integer quotient of [x] and [y].
|
||||
Integer division. Raise [Division_by_zero] if the second
|
||||
argument [y] is zero. This division rounds the real quotient of
|
||||
its arguments towards zero, as specified for {!Stdlib.(/)}. *)
|
||||
|
||||
val ( mod ) : t -> t -> t
|
||||
(** [x mod y] is the integer remainder of [x / y].
|
||||
If [y <> zero], the result of [x mod y] satisfies the following properties:
|
||||
[zero <= x mod y < abs y] and
|
||||
[x = ((x / y) * y) + (x mod y)].
|
||||
If [y = 0], [x mod y] raises [Division_by_zero]. *)
|
||||
|
||||
val ( ** ) : t -> t -> t
|
||||
(** Alias to {!pow}
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val (--) : t -> t -> t iter
|
||||
(** Alias to {!range}.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val (--^) : t -> t -> t iter
|
||||
(** Alias to {!range'}.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val ( land ) : t -> t -> t
|
||||
(** [x land y] is the bitwise logical and of [x] and [y]. *)
|
||||
|
||||
val ( lor ) : t -> t -> t
|
||||
(** [x lor y] is the bitwise logical or of [x] and [y]. *)
|
||||
|
||||
val ( lxor ) : t -> t -> t
|
||||
(** [x lxor y] is the bitwise logical exclusive or of [x] and [y]. *)
|
||||
|
||||
val lnot : t -> t
|
||||
(** [lnot x] is the bitwise logical negation of [x] (the bits of [x] are inverted). *)
|
||||
|
||||
val ( lsl ) : t -> int -> t
|
||||
(** [ x lsl y] shifts [x] to the left by [y] bits, filling in with zeroes.
|
||||
The result is unspecified if [y < 0] or [y >= 32]. *)
|
||||
|
||||
val ( lsr ) : t -> int -> t
|
||||
(** [x lsr y] shifts [x] to the right by [y] bits.
|
||||
This is a logical shift: zeroes are inserted in the vacated bits
|
||||
regardless of the sign of [x].
|
||||
The result is unspecified if [y < 0] or [y >= 32]. *)
|
||||
|
||||
val ( asr ) : t -> int -> t
|
||||
(** [x asr y] shifts [x] to the right by [y] bits.
|
||||
This is an arithmetic shift: the sign bit of [x] is replicated
|
||||
and inserted in the vacated bits.
|
||||
The result is unspecified if [y < 0] or [y >= 32]. *)
|
||||
|
||||
val (=) : t -> t -> bool
|
||||
val (<>) : t -> t -> bool
|
||||
val (>) : t -> t -> bool
|
||||
val (>=) : t -> t -> bool
|
||||
val (<=) : t -> t -> bool
|
||||
val (<) : t -> t -> bool
|
||||
end
|
||||
|
||||
include module type of Infix
|
||||
|
|
|
|||
|
|
@ -3,6 +3,200 @@
|
|||
open CCShims_
|
||||
include Int64
|
||||
|
||||
|
||||
let min : t -> t -> t = Stdlib.min
|
||||
let max : t -> t -> t = Stdlib.max
|
||||
|
||||
let hash x = Stdlib.abs (to_int x)
|
||||
|
||||
let sign i = compare i zero
|
||||
|
||||
let pow a b =
|
||||
let rec aux acc = function
|
||||
| 1L -> acc
|
||||
| n ->
|
||||
if equal (rem n 2L) zero
|
||||
then aux (mul acc acc) (div n 2L)
|
||||
else mul acc (aux (mul acc acc) (div n 2L))
|
||||
in
|
||||
match b with
|
||||
| 0L -> if equal a 0L then raise (Invalid_argument "pow: undefined value 0^0") else 1L
|
||||
| b when compare b 0L < 0 -> raise (Invalid_argument "pow: can't raise int to negative power")
|
||||
| b -> aux a b
|
||||
|
||||
(*$T
|
||||
pow 2L 10L = 1024L
|
||||
pow 2L 15L = 32768L
|
||||
pow 10L 5L = 100000L
|
||||
pow 42L 0L = 1L
|
||||
pow 0L 1L = 0L
|
||||
*)
|
||||
|
||||
let floor_div a n =
|
||||
if compare a 0L < 0 && compare n 0L >= 0 then
|
||||
sub (div (add a 1L) n) 1L
|
||||
else if compare a 0L > 0 && compare n 0L < 0 then
|
||||
sub (div (sub a 1L) n) 1L
|
||||
else
|
||||
div a n
|
||||
|
||||
(*$T
|
||||
(floor_div 3L 5L = 0L)
|
||||
(floor_div 5L 5L = 1L)
|
||||
(floor_div 20L 5L = 4L)
|
||||
(floor_div 12L 5L = 2L)
|
||||
(floor_div 0L 5L = 0L)
|
||||
(floor_div (-1L) 5L = -1L)
|
||||
(floor_div (-5L) 5L = -1L)
|
||||
(floor_div (-12L) 5L = -3L)
|
||||
|
||||
(floor_div 0L (-5L) = 0L)
|
||||
(floor_div 3L (-5L) = -1L)
|
||||
(floor_div 5L (-5L) = -1L)
|
||||
(floor_div 9L (-5L) = -2L)
|
||||
(floor_div 20L (-5L) = -4L)
|
||||
(floor_div (-2L) (-5L) = 0L)
|
||||
(floor_div (-8L) (-5L) = 1L)
|
||||
(floor_div (-35L) (-5L) = 7L)
|
||||
|
||||
try ignore (floor_div 12L 0L); false with Division_by_zero -> true
|
||||
try ignore (floor_div (-12L) 0L); false with Division_by_zero -> true
|
||||
*)
|
||||
|
||||
(*$Q
|
||||
(Q.pair (Q.map of_int Q.small_signed_int) (Q.map of_int Q.small_nat)) \
|
||||
(fun (n, m) -> let m = m + 1L in \
|
||||
floor_div n m = of_float @@ floor (to_float n /. to_float m))
|
||||
(Q.pair (Q.map of_int Q.small_signed_int) (Q.map of_int Q.small_nat)) \
|
||||
(fun (n, m) -> let m = m + 1L in \
|
||||
floor_div n (-m) = of_float @@ floor (to_float n /. to_float (-m)))
|
||||
*)
|
||||
|
||||
type 'a printer = Format.formatter -> 'a -> unit
|
||||
type 'a random_gen = Random.State.t -> 'a
|
||||
type 'a iter = ('a -> unit) -> unit
|
||||
|
||||
let range i j yield =
|
||||
let rec up i j yield =
|
||||
if equal i j then yield i
|
||||
else (
|
||||
yield i;
|
||||
up (add i 1L) j yield
|
||||
)
|
||||
and down i j yield =
|
||||
if equal i j then yield i
|
||||
else (
|
||||
yield i;
|
||||
down (sub i 1L) j yield
|
||||
)
|
||||
in
|
||||
if compare i j <= 0 then up i j yield else down i j yield
|
||||
|
||||
(*$= & ~printer:Q.Print.(list to_string)
|
||||
[0L;1L;2L;3L;4L;5L] (range 0L 5L |> Iter.to_list)
|
||||
[0L] (range 0L 0L |> Iter.to_list)
|
||||
[5L;4L;3L;2L] (range 5L 2L |> Iter.to_list)
|
||||
*)
|
||||
|
||||
let range' i j yield =
|
||||
if compare i j < 0 then range i (sub j 1L) yield
|
||||
else if equal i j then ()
|
||||
else range i (add j 1L) yield
|
||||
|
||||
let range_by ~step i j yield =
|
||||
let rec range i j yield =
|
||||
if equal i j then yield i
|
||||
else (
|
||||
yield i;
|
||||
range (add i step) j yield
|
||||
)
|
||||
in
|
||||
if equal step 0L then
|
||||
raise (Invalid_argument "CCInt64.range_by")
|
||||
else if (if compare step 0L > 0 then compare i j > 0 else compare i j < 0) then ()
|
||||
else range i (add (mul (div (sub j i) step) step) i) yield
|
||||
|
||||
(* note: the last test checks that no error occurs due to overflows. *)
|
||||
(*$= & ~printer:Q.Print.(list to_string)
|
||||
[0L] (range_by ~step:1L 0L 0L |> Iter.to_list)
|
||||
[] (range_by ~step:1L 5L 0L |> Iter.to_list)
|
||||
[] (range_by ~step:2L 1L 0L |> Iter.to_list)
|
||||
[0L;2L;4L] (range_by ~step:2L 0L 4L |> Iter.to_list)
|
||||
[0L;2L;4L] (range_by ~step:2L 0L 5L |> Iter.to_list)
|
||||
[0L] (range_by ~step:(neg 1L) 0L 0L |> Iter.to_list)
|
||||
[] (range_by ~step:(neg 1L) 0L 5L |> Iter.to_list)
|
||||
[] (range_by ~step:(neg 2L) 0L 1L |> Iter.to_list)
|
||||
[5L;3L;1L] (range_by ~step:(neg 2L) 5L 1L |> Iter.to_list)
|
||||
[5L;3L;1L] (range_by ~step:(neg 2L) 5L 0L |> Iter.to_list)
|
||||
[0L] (range_by ~step:max_int 0L 2L |> Iter.to_list)
|
||||
*)
|
||||
|
||||
(*$Q
|
||||
Q.(pair (map of_int small_int) (map of_int small_int)) (fun (i,j) -> \
|
||||
let i = min i j and j = max i j in \
|
||||
CCList.equal CCInt64.equal \
|
||||
(CCInt64.range_by ~step:1L i j |> Iter.to_list) \
|
||||
(CCInt64.range i j |> Iter.to_list) )
|
||||
*)
|
||||
|
||||
let random n st = Random.State.int64 st n
|
||||
let random_small = random 100L
|
||||
let random_range i j st = add i (random (sub j i) st)
|
||||
|
||||
|
||||
(** {2 Conversion} *)
|
||||
|
||||
let of_string_exn = of_string
|
||||
|
||||
let of_string x = try Some (of_string_exn x) with Failure _ -> None
|
||||
let of_string_opt = of_string
|
||||
|
||||
let most_significant_bit =
|
||||
logxor (neg 1L) (shift_right_logical (neg 1L) 1)
|
||||
|
||||
type output = char -> unit
|
||||
|
||||
(* abstract printer *)
|
||||
let to_binary_gen (out:output) n =
|
||||
let n = if compare n 0L <0 then (out '-'; neg n) else n in
|
||||
out '0'; out 'b';
|
||||
let rec loop started bit n =
|
||||
if equal bit 0L then (
|
||||
if not started then out '0'
|
||||
) else (
|
||||
let b = logand n bit in
|
||||
if equal b 0L then (
|
||||
if started then out '0';
|
||||
loop started (shift_right_logical bit 1) n
|
||||
) else (
|
||||
out '1';
|
||||
loop true (shift_right_logical bit 1) n
|
||||
)
|
||||
)
|
||||
in
|
||||
loop false most_significant_bit n
|
||||
|
||||
let to_string_binary n =
|
||||
let buf = Buffer.create 16 in
|
||||
to_binary_gen (Buffer.add_char buf) n;
|
||||
Buffer.contents buf
|
||||
|
||||
(*$= & ~printer:CCFun.id
|
||||
"0b111" (to_string_binary 7L)
|
||||
"-0b111" (to_string_binary (-7L))
|
||||
"0b0" (to_string_binary 0L)
|
||||
*)
|
||||
|
||||
(** {2 Printing} *)
|
||||
|
||||
let pp out n = Format.pp_print_string out (to_string n)
|
||||
|
||||
let pp_binary out n =
|
||||
to_binary_gen (Format.pp_print_char out) n
|
||||
|
||||
|
||||
(** {2 Infix Operators} *)
|
||||
|
||||
module Infix = struct
|
||||
let (+) = add
|
||||
|
||||
|
|
@ -14,6 +208,12 @@ module Infix = struct
|
|||
|
||||
let (/) = div
|
||||
|
||||
let ( ** ) = pow
|
||||
|
||||
let (--) = range
|
||||
|
||||
let (--^) = range'
|
||||
|
||||
let (mod) = rem
|
||||
|
||||
let (land) = logand
|
||||
|
|
@ -38,14 +238,4 @@ module Infix = struct
|
|||
let (>) = Stdlib.(>)
|
||||
let (>=) = Stdlib.(>=)
|
||||
end
|
||||
|
||||
include Infix
|
||||
|
||||
let hash x = Stdlib.abs (to_int x)
|
||||
|
||||
(** {2 Conversion} *)
|
||||
|
||||
let of_string_exn = of_string
|
||||
|
||||
let of_string x = try Some (of_string_exn x) with Failure _ -> None
|
||||
let of_string_opt = of_string
|
||||
|
|
|
|||
|
|
@ -2,169 +2,81 @@
|
|||
|
||||
(** {1 Int64}
|
||||
|
||||
Helpers for 64-bit integers
|
||||
Helpers for 64-bit integers.
|
||||
|
||||
This module provides operations on the type int64 of signed 64-bit integers.
|
||||
Unlike the built-in int type, the type int64 is guaranteed to be exactly
|
||||
64-bit wide on all platforms. All arithmetic operations over int64 are taken
|
||||
modulo 2{^64}.
|
||||
|
||||
Performance notice: values of type int64 occupy more memory space than values
|
||||
of type int, and arithmetic operations on int64 are generally slower than
|
||||
those on int. Use int64 only when the application requires exact 64-bit arithmetic.
|
||||
|
||||
@since 0.13 *)
|
||||
|
||||
include module type of struct include Int64 end
|
||||
|
||||
val ( + ) : t -> t -> t
|
||||
(** [x + y] is the sum of [x] and [y].
|
||||
Addition. *)
|
||||
val min : t -> t -> t
|
||||
(** [min x y] returns the minimum of the two integers [x] and [y].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val ( - ) : t -> t -> t
|
||||
(** [x - y] is the difference of [x] and [y].
|
||||
Subtraction. *)
|
||||
|
||||
val ( ~- ) : t -> t
|
||||
(** [~- x] is the negation of [x].
|
||||
Unary negation. *)
|
||||
|
||||
val ( * ) : t -> t -> t
|
||||
(** [ x * y] is the product of [x] and [y].
|
||||
Multiplication. *)
|
||||
|
||||
val ( / ) : t -> t -> t
|
||||
(** [x / y] is the integer quotient of [x] and [y].
|
||||
Integer division. Raise [Division_by_zero] if the second
|
||||
argument [y] is zero. This division rounds the real quotient of
|
||||
its arguments towards zero, as specified for {!Stdlib.(/)}. *)
|
||||
|
||||
val ( mod ) : t -> t -> t
|
||||
(** [x mod y] is the integer remainder of [x / y].
|
||||
If [y <> zero], the result of [x mod y] satisfies the following property:
|
||||
[x = ((x / y) * y) + (x mod y)].
|
||||
If [y = 0], [x mod y] raises [Division_by_zero]. *)
|
||||
|
||||
val abs : t -> t
|
||||
(** [abs x] returns the absolute value (or magnitude) of its argument [x]. *)
|
||||
|
||||
val max_int : t
|
||||
(** [max_int] is the greatest representable 64-bit integer, 2{^63} - 1 = [9_223_372_036_854_775_807]. *)
|
||||
|
||||
val min_int : t
|
||||
(** [min_int] is the smallest representable 64-bit integer, -2{^63} = [-9_223_372_036_854_775_808]. *)
|
||||
|
||||
val ( land ) : t -> t -> t
|
||||
(** [x land y] is the bitwise logical and of [x] and [y]. *)
|
||||
|
||||
val ( lor ) : t -> t -> t
|
||||
(** [x lor y] is the bitwise logical or of [x] and [y]. *)
|
||||
|
||||
val ( lxor ) : t -> t -> t
|
||||
(** [x lxor y] is the bitwise logical exclusive or of [x] and [y]. *)
|
||||
|
||||
val lnot : t -> t
|
||||
(** [lnot x] is the bitwise logical negation of [x] (the bits of [x] are inverted). *)
|
||||
|
||||
val ( lsl ) : t -> int -> t
|
||||
(** [ x lsl y] shifts [x] to the left by [y] bits, filling in with zeroes.
|
||||
The result is unspecified if [y < 0] or [y >= 64]. *)
|
||||
|
||||
val ( lsr ) : t -> int -> t
|
||||
(** [x lsr y] shifts [x] to the right by [y] bits.
|
||||
This is a logical shift: zeroes are inserted in the vacated bits
|
||||
regardless of the sign of [x].
|
||||
The result is unspecified if [y < 0] or [y >= 64]. *)
|
||||
|
||||
val ( asr ) : t -> int -> t
|
||||
(** [x asr y] shifts [x] to the right by [y] bits.
|
||||
This is an arithmetic shift: the sign bit of [x] is replicated
|
||||
and inserted in the vacated bits.
|
||||
The result is unspecified if [y < 0] or [y >= 64]. *)
|
||||
|
||||
(** Infix operators
|
||||
@since 2.1 *)
|
||||
module Infix : sig
|
||||
val (+) : t -> t -> t
|
||||
val (-) : t -> t -> t
|
||||
val (~-) : t -> t
|
||||
val ( * ) : t -> t -> t
|
||||
val (/) : t -> t -> t
|
||||
val (mod) : t -> t -> t
|
||||
val (land) : t -> t -> t
|
||||
val (lor) : t -> t -> t
|
||||
val (lxor) : t -> t -> t
|
||||
val lnot : t -> t
|
||||
val (lsl) : t -> int -> t
|
||||
val (lsr) : t -> int -> t
|
||||
val (asr) : t -> int -> t
|
||||
val (=) : t -> t -> bool
|
||||
val (<>) : t -> t -> bool
|
||||
val (>) : t -> t -> bool
|
||||
val (>=) : t -> t -> bool
|
||||
val (<=) : t -> t -> bool
|
||||
val (<) : t -> t -> bool
|
||||
end
|
||||
|
||||
include module type of Infix
|
||||
|
||||
val compare : t -> t -> int
|
||||
(** [compare x y] is the comparison function for 64-bit integers, with the same specification as
|
||||
{!Stdlib.compare}. Along with the type [t], this function [compare]
|
||||
allows the module [CCInt64] to be passed as argument to the functors
|
||||
{!Set.Make} and {!Map.Make}. *)
|
||||
val max : t -> t -> t
|
||||
(** [max x y] returns the maximum of the two integers [x] and [y].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val hash : t -> int
|
||||
(** [hash x] computes the hash of [x].
|
||||
Like {!Stdlib.abs (to_int x)}. *)
|
||||
|
||||
|
||||
val sign : t -> int
|
||||
(** [sign x] return [0] if [x = 0], [-1] if [x < 0] and [1] if [x > 0].
|
||||
Same as [compare x zero].
|
||||
@since NEXT_RELEASE*)
|
||||
|
||||
val pow : t -> t -> t
|
||||
(** [pow base exponent] returns [base] raised to the power of [exponent].
|
||||
[pow x y = x^y] for positive integers [x] and [y].
|
||||
Raises [Invalid_argument] if [x = y = 0] or [y] < 0.
|
||||
@since 0.11 *)
|
||||
|
||||
val floor_div : t -> t -> t
|
||||
(** [floor_div x n] is integer division rounding towards negative infinity.
|
||||
It satisfies [x = m * floor_div x n + rem x n].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
type 'a printer = Format.formatter -> 'a -> unit
|
||||
type 'a random_gen = Random.State.t -> 'a
|
||||
type 'a iter = ('a -> unit) -> unit
|
||||
|
||||
|
||||
val range_by : step:t -> t -> t -> t iter
|
||||
(** [range_by ~step i j] iterates on integers from [i] to [j] included,
|
||||
where the difference between successive elements is [step].
|
||||
Use a negative [step] for a decreasing list.
|
||||
@raise Invalid_argument if [step=0].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val range : t -> t -> t iter
|
||||
(** [range i j] iterates on integers from [i] to [j] included . It works
|
||||
both for decreasing and increasing ranges.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val range' : t -> t -> t iter
|
||||
(** [range' i j] is like {!range} but the second bound [j] is excluded.
|
||||
For instance [range' 0 5 = Iter.of_list [0;1;2;3;4]].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val random : t -> t random_gen
|
||||
val random_small : t random_gen
|
||||
val random_range : t -> t -> t random_gen
|
||||
|
||||
|
||||
(** {2 Conversion} *)
|
||||
|
||||
val to_int : t -> int
|
||||
(** [to_int x] converts the given 64-bit integer [x] (type [int64]) into an
|
||||
integer (type [int]). On 64-bit platforms, the 64-bit integer
|
||||
is taken modulo 2{^63}, i.e. the high-order bit is lost
|
||||
during the conversion. On 32-bit platforms, the 64-bit integer
|
||||
is taken modulo 2{^31}, i.e. the top 33 bits are lost
|
||||
during the conversion. *)
|
||||
|
||||
val of_int : int -> t
|
||||
(** [of_int x] converts the given integer [x] (type [int]) into an
|
||||
64-bit integer (type [int64]).
|
||||
Alias to {!Int64.of_int}.
|
||||
NOTE: used to return an option, but the function actually never fails. *)
|
||||
|
||||
val to_int32 : t -> int32
|
||||
(** [to_int32 x] converts the given 64-bit integer [x] (type [int64]) to a
|
||||
32-bit integer (type [int32]). The 64-bit integer
|
||||
is taken modulo 2{^32}, i.e. the top 32 bits are lost
|
||||
during the conversion. *)
|
||||
|
||||
val of_int32 : int32 -> t
|
||||
(** [of_int32 x] converts the given 32-bit integer [x] (type [int32]) into an
|
||||
64-bit integer (type [int64]).
|
||||
Alias to {!Int64.of_int32}.
|
||||
NOTE: use to return an option, but the function actually never fails. *)
|
||||
|
||||
val to_nativeint : t -> nativeint
|
||||
(** [to_nativeint x] converts the given 64-bit integer [x] (type [int64]) into a
|
||||
native integer. On 32-bit platforms, the 64-bit integer
|
||||
is taken modulo 2{^32}. On 64-bit platforms,
|
||||
the conversion is exact. *)
|
||||
|
||||
val of_nativeint : nativeint -> t
|
||||
(** [of_nativeint x] converts the given nativeint integer [x] (type [nativeint]) into an
|
||||
64-bit integer (type [int64]).
|
||||
Alias to {!Int64.of_nativeint}.
|
||||
NOTE: use to return an option, but the function actually never fails. *)
|
||||
|
||||
val to_float : t -> float
|
||||
(** [to_float x] converts the given 64-bit integer [x] into a floating-point number. *)
|
||||
|
||||
val of_float : float -> t
|
||||
(** [of_float x] converts the given floating-point number [x] into a 64-bit integer,
|
||||
discarding the fractional part (truncate towards 0).
|
||||
The result of the conversion is undefined if, after truncation,
|
||||
the number is outside the range \[{!CCInt64.min_int}, {!CCInt64.max_int}\].
|
||||
Alias to {!Int64.of_float}.
|
||||
NOTE: used to return an option, but the function never fails. *)
|
||||
|
||||
val to_string : t -> string
|
||||
(** [to_string x] returns the string representation of its argument [x], in decimal. *)
|
||||
|
||||
val of_string : string -> t option
|
||||
(** [of_string s] is the safe version of {!of_string_exn}. *)
|
||||
(** [of_string s] is the safe version of {!of_string_exn}.
|
||||
Like {!of_string_exn}, but return [None] instead of raising. *)
|
||||
|
||||
val of_string_opt : string -> t option
|
||||
(** [of_string_opt s] is an alias to {!of_string}.
|
||||
|
|
@ -187,3 +99,104 @@ val of_string_exn : string -> t
|
|||
Raise [Failure "Int64.of_string"] if the given string is not
|
||||
a valid representation of an integer, or if the integer represented
|
||||
exceeds the range of integers representable in type [int64]. *)
|
||||
|
||||
val to_string_binary : t -> string
|
||||
(** [to_string_binary x] returns the string representation of the integer [x], in binary.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
|
||||
(** {2 Printing} *)
|
||||
|
||||
val pp : t printer
|
||||
(** [pp ppf x] prints the integer [x] on [ppf].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val pp_binary : t printer
|
||||
(** [pp_binary ppf x] prints [x] on [ppf].
|
||||
Print as "0b00101010".
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
|
||||
(** {2 Infix Operators} *)
|
||||
(** Infix operators
|
||||
@since 2.1 *)
|
||||
|
||||
module Infix : sig
|
||||
val ( + ) : t -> t -> t
|
||||
(** [x + y] is the sum of [x] and [y].
|
||||
Addition. *)
|
||||
|
||||
val ( - ) : t -> t -> t
|
||||
(** [x - y] is the difference of [x] and [y].
|
||||
Subtraction. *)
|
||||
|
||||
val ( ~- ) : t -> t
|
||||
(** [~- x] is the negation of [x].
|
||||
Unary negation. *)
|
||||
|
||||
val ( * ) : t -> t -> t
|
||||
(** [ x * y] is the product of [x] and [y].
|
||||
Multiplication. *)
|
||||
|
||||
val ( / ) : t -> t -> t
|
||||
(** [x / y] is the integer quotient of [x] and [y].
|
||||
Integer division. Raise [Division_by_zero] if the second
|
||||
argument [y] is zero. This division rounds the real quotient of
|
||||
its arguments towards zero, as specified for {!Stdlib.(/)}. *)
|
||||
|
||||
val ( mod ) : t -> t -> t
|
||||
(** [x mod y] is the integer remainder of [x / y].
|
||||
If [y <> zero], the result of [x mod y] satisfies the following properties:
|
||||
[zero <= x mod y < abs y] and
|
||||
[x = ((x / y) * y) + (x mod y)].
|
||||
If [y = 0], [x mod y] raises [Division_by_zero]. *)
|
||||
|
||||
val ( ** ) : t -> t -> t
|
||||
(** Alias to {!pow}
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val (--) : t -> t -> t iter
|
||||
(** Alias to {!range}.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val (--^) : t -> t -> t iter
|
||||
(** Alias to {!range'}.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val ( land ) : t -> t -> t
|
||||
(** [x land y] is the bitwise logical and of [x] and [y]. *)
|
||||
|
||||
val ( lor ) : t -> t -> t
|
||||
(** [x lor y] is the bitwise logical or of [x] and [y]. *)
|
||||
|
||||
val ( lxor ) : t -> t -> t
|
||||
(** [x lxor y] is the bitwise logical exclusive or of [x] and [y]. *)
|
||||
|
||||
val lnot : t -> t
|
||||
(** [lnot x] is the bitwise logical negation of [x] (the bits of [x] are inverted). *)
|
||||
|
||||
val ( lsl ) : t -> int -> t
|
||||
(** [ x lsl y] shifts [x] to the left by [y] bits, filling in with zeroes.
|
||||
The result is unspecified if [y < 0] or [y >= 64]. *)
|
||||
|
||||
val ( lsr ) : t -> int -> t
|
||||
(** [x lsr y] shifts [x] to the right by [y] bits.
|
||||
This is a logical shift: zeroes are inserted in the vacated bits
|
||||
regardless of the sign of [x].
|
||||
The result is unspecified if [y < 0] or [y >= 64]. *)
|
||||
|
||||
val ( asr ) : t -> int -> t
|
||||
(** [x asr y] shifts [x] to the right by [y] bits.
|
||||
This is an arithmetic shift: the sign bit of [x] is replicated
|
||||
and inserted in the vacated bits.
|
||||
The result is unspecified if [y < 0] or [y >= 64]. *)
|
||||
|
||||
val (=) : t -> t -> bool
|
||||
val (<>) : t -> t -> bool
|
||||
val (>) : t -> t -> bool
|
||||
val (>=) : t -> t -> bool
|
||||
val (<=) : t -> t -> bool
|
||||
val (<) : t -> t -> bool
|
||||
end
|
||||
|
||||
include module type of Infix
|
||||
|
|
|
|||
|
|
@ -3,6 +3,200 @@
|
|||
open CCShims_
|
||||
include Nativeint
|
||||
|
||||
|
||||
let min : t -> t -> t = Stdlib.min
|
||||
let max : t -> t -> t = Stdlib.max
|
||||
|
||||
let hash x = Stdlib.abs (to_int x)
|
||||
|
||||
let sign i = compare i zero
|
||||
|
||||
let pow a b =
|
||||
let rec aux acc = function
|
||||
| 1n -> acc
|
||||
| n ->
|
||||
if equal (rem n 2n) zero
|
||||
then aux (mul acc acc) (div n 2n)
|
||||
else mul acc (aux (mul acc acc) (div n 2n))
|
||||
in
|
||||
match b with
|
||||
| 0n -> if equal a 0n then raise (Invalid_argument "pow: undefined value 0^0") else 1n
|
||||
| b when compare b 0n < 0 -> raise (Invalid_argument "pow: can't raise int to negative power")
|
||||
| b -> aux a b
|
||||
|
||||
(*$T
|
||||
pow 2n 10n = 1024n
|
||||
pow 2n 15n = 32768n
|
||||
pow 10n 5n = 100000n
|
||||
pow 42n 0n = 1n
|
||||
pow 0n 1n = 0n
|
||||
*)
|
||||
|
||||
let floor_div a n =
|
||||
if compare a 0n < 0 && compare n 0n >= 0 then
|
||||
sub (div (add a 1n) n) 1n
|
||||
else if compare a 0n > 0 && compare n 0n < 0 then
|
||||
sub (div (sub a 1n) n) 1n
|
||||
else
|
||||
div a n
|
||||
|
||||
(*$T
|
||||
(floor_div 3n 5n = 0n)
|
||||
(floor_div 5n 5n = 1n)
|
||||
(floor_div 20n 5n = 4n)
|
||||
(floor_div 12n 5n = 2n)
|
||||
(floor_div 0n 5n = 0n)
|
||||
(floor_div (-1n) 5n = -1n)
|
||||
(floor_div (-5n) 5n = -1n)
|
||||
(floor_div (-12n) 5n = -3n)
|
||||
|
||||
(floor_div 0n (-5n) = 0n)
|
||||
(floor_div 3n (-5n) = -1n)
|
||||
(floor_div 5n (-5n) = -1n)
|
||||
(floor_div 9n (-5n) = -2n)
|
||||
(floor_div 20n (-5n) = -4n)
|
||||
(floor_div (-2n) (-5n) = 0n)
|
||||
(floor_div (-8n) (-5n) = 1n)
|
||||
(floor_div (-35n) (-5n) = 7n)
|
||||
|
||||
try ignore (floor_div 12n 0n); false with Division_by_zero -> true
|
||||
try ignore (floor_div (-12n) 0n); false with Division_by_zero -> true
|
||||
*)
|
||||
|
||||
(*$Q
|
||||
(Q.pair (Q.map of_int Q.small_signed_int) (Q.map of_int Q.small_nat)) \
|
||||
(fun (n, m) -> let m = m + 1n in \
|
||||
floor_div n m = of_float @@ floor (to_float n /. to_float m))
|
||||
(Q.pair (Q.map of_int Q.small_signed_int) (Q.map of_int Q.small_nat)) \
|
||||
(fun (n, m) -> let m = m + 1n in \
|
||||
floor_div n (-m) = of_float @@ floor (to_float n /. to_float (-m)))
|
||||
*)
|
||||
|
||||
type 'a printer = Format.formatter -> 'a -> unit
|
||||
type 'a random_gen = Random.State.t -> 'a
|
||||
type 'a iter = ('a -> unit) -> unit
|
||||
|
||||
let range i j yield =
|
||||
let rec up i j yield =
|
||||
if equal i j then yield i
|
||||
else (
|
||||
yield i;
|
||||
up (add i 1n) j yield
|
||||
)
|
||||
and down i j yield =
|
||||
if equal i j then yield i
|
||||
else (
|
||||
yield i;
|
||||
down (sub i 1n) j yield
|
||||
)
|
||||
in
|
||||
if compare i j <= 0 then up i j yield else down i j yield
|
||||
|
||||
(*$= & ~printer:Q.Print.(list to_string)
|
||||
[0n;1n;2n;3n;4n;5n] (range 0n 5n |> Iter.to_list)
|
||||
[0n] (range 0n 0n |> Iter.to_list)
|
||||
[5n;4n;3n;2n] (range 5n 2n |> Iter.to_list)
|
||||
*)
|
||||
|
||||
let range' i j yield =
|
||||
if compare i j < 0 then range i (sub j 1n) yield
|
||||
else if equal i j then ()
|
||||
else range i (add j 1n) yield
|
||||
|
||||
let range_by ~step i j yield =
|
||||
let rec range i j yield =
|
||||
if equal i j then yield i
|
||||
else (
|
||||
yield i;
|
||||
range (add i step) j yield
|
||||
)
|
||||
in
|
||||
if equal step 0n then
|
||||
raise (Invalid_argument "CCNativeint.range_by")
|
||||
else if (if compare step 0n > 0 then compare i j > 0 else compare i j < 0) then ()
|
||||
else range i (add (mul (div (sub j i) step) step) i) yield
|
||||
|
||||
(* note: the last test checks that no error occurs due to overflows. *)
|
||||
(*$= & ~printer:Q.Print.(list to_string)
|
||||
[0n] (range_by ~step:1n 0n 0n |> Iter.to_list)
|
||||
[] (range_by ~step:1n 5n 0n |> Iter.to_list)
|
||||
[] (range_by ~step:2n 1n 0n |> Iter.to_list)
|
||||
[0n;2n;4n] (range_by ~step:2n 0n 4n |> Iter.to_list)
|
||||
[0n;2n;4n] (range_by ~step:2n 0n 5n |> Iter.to_list)
|
||||
[0n] (range_by ~step:(neg 1n) 0n 0n |> Iter.to_list)
|
||||
[] (range_by ~step:(neg 1n) 0n 5n |> Iter.to_list)
|
||||
[] (range_by ~step:(neg 2n) 0n 1n |> Iter.to_list)
|
||||
[5n;3n;1n] (range_by ~step:(neg 2n) 5n 1n |> Iter.to_list)
|
||||
[5n;3n;1n] (range_by ~step:(neg 2n) 5n 0n |> Iter.to_list)
|
||||
[0n] (range_by ~step:max_int 0n 2n |> Iter.to_list)
|
||||
*)
|
||||
|
||||
(*$Q
|
||||
Q.(pair (map of_int small_int) (map of_int small_int)) (fun (i,j) -> \
|
||||
let i = min i j and j = max i j in \
|
||||
CCList.equal CCNativeint.equal \
|
||||
(CCNativeint.range_by ~step:1n i j |> Iter.to_list) \
|
||||
(CCNativeint.range i j |> Iter.to_list) )
|
||||
*)
|
||||
|
||||
let random n st = Random.State.nativeint st n
|
||||
let random_small = random 100n
|
||||
let random_range i j st = add i (random (sub j i) st)
|
||||
|
||||
|
||||
(** {2 Conversion} *)
|
||||
|
||||
let of_string_exn = of_string
|
||||
|
||||
let of_string x = try Some (of_string_exn x) with Failure _ -> None
|
||||
let of_string_opt = of_string
|
||||
|
||||
let most_significant_bit =
|
||||
logxor (neg 1n) (shift_right_logical (neg 1n) 1)
|
||||
|
||||
type output = char -> unit
|
||||
|
||||
(* abstract printer *)
|
||||
let to_binary_gen (out:output) n =
|
||||
let n = if compare n 0n <0 then (out '-'; neg n) else n in
|
||||
out '0'; out 'b';
|
||||
let rec loop started bit n =
|
||||
if equal bit 0n then (
|
||||
if not started then out '0'
|
||||
) else (
|
||||
let b = logand n bit in
|
||||
if equal b 0n then (
|
||||
if started then out '0';
|
||||
loop started (shift_right_logical bit 1) n
|
||||
) else (
|
||||
out '1';
|
||||
loop true (shift_right_logical bit 1) n
|
||||
)
|
||||
)
|
||||
in
|
||||
loop false most_significant_bit n
|
||||
|
||||
let to_string_binary n =
|
||||
let buf = Buffer.create 16 in
|
||||
to_binary_gen (Buffer.add_char buf) n;
|
||||
Buffer.contents buf
|
||||
|
||||
(*$= & ~printer:CCFun.id
|
||||
"0b111" (to_string_binary 7n)
|
||||
"-0b111" (to_string_binary (-7n))
|
||||
"0b0" (to_string_binary 0n)
|
||||
*)
|
||||
|
||||
(** {2 Printing} *)
|
||||
|
||||
let pp out n = Format.pp_print_string out (to_string n)
|
||||
|
||||
let pp_binary out n =
|
||||
to_binary_gen (Format.pp_print_char out) n
|
||||
|
||||
|
||||
(** {2 Infix Operators} *)
|
||||
|
||||
module Infix = struct
|
||||
let (+) = add
|
||||
|
||||
|
|
@ -14,6 +208,12 @@ module Infix = struct
|
|||
|
||||
let (/) = div
|
||||
|
||||
let ( ** ) = pow
|
||||
|
||||
let (--) = range
|
||||
|
||||
let (--^) = range'
|
||||
|
||||
let (mod) = rem
|
||||
|
||||
let (land) = logand
|
||||
|
|
@ -39,12 +239,3 @@ module Infix = struct
|
|||
let (>=) = Stdlib.(>=)
|
||||
end
|
||||
include Infix
|
||||
|
||||
let hash x = Stdlib.abs (to_int x)
|
||||
|
||||
(** {2 Conversion} *)
|
||||
|
||||
let of_string_exn = of_string
|
||||
|
||||
let of_string x = try Some (of_string_exn x) with Failure _ -> None
|
||||
let of_string_opt = of_string
|
||||
|
|
|
|||
|
|
@ -18,110 +18,73 @@
|
|||
|
||||
include module type of struct include Nativeint end
|
||||
|
||||
val ( + ) : t -> t -> t
|
||||
(** Addition. *)
|
||||
val min : t -> t -> t
|
||||
(** [min x y] returns the minimum of the two integers [x] and [y].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val ( - ) : t -> t -> t
|
||||
(** Subtraction. *)
|
||||
|
||||
val ( ~- ) : t -> t
|
||||
(** Unary negation. *)
|
||||
|
||||
val ( * ) : t -> t -> t
|
||||
(** Multiplication. *)
|
||||
|
||||
val ( / ) : t -> t -> t
|
||||
(** Integer division. Raise [Division_by_zero] if the second
|
||||
argument is zero. This division rounds the real quotient of
|
||||
its arguments towards zero, as specified for {!Stdlib.(/)}. *)
|
||||
|
||||
val ( mod ) : t -> t -> t
|
||||
(** [x mod y ] is the integer remainder.
|
||||
If [y <> zero], the result of [x mod y] satisfies the following properties:
|
||||
[zero <= x mod y < abs y] and
|
||||
[x = ((x / y) * y) + (x mod y)].
|
||||
If [y = 0], [x mod y] raises [Division_by_zero]. *)
|
||||
|
||||
val ( land ) : t -> t -> t
|
||||
(** Bitwise logical and. *)
|
||||
|
||||
val ( lor ) : t -> t -> t
|
||||
(** Bitwise logical or. *)
|
||||
|
||||
val ( lxor ) : t -> t -> t
|
||||
(** Bitwise logical exclusive or. *)
|
||||
|
||||
val lnot : t -> t
|
||||
(** Bitwise logical negation. *)
|
||||
|
||||
val ( lsl ) : t -> int -> t
|
||||
(** [ x lsl y] shifts [x] to the left by [y] bits.
|
||||
The result is unspecified if [y < 0] or [y >= bitsize], where [bitsize] is [32] on a 32-bit platform
|
||||
and [64] on a 64-bit platform. *)
|
||||
|
||||
val ( lsr ) : t -> int -> t
|
||||
(** [x lsr y] shifts [x] to the right by [y] bits.
|
||||
This is a logical shift: zeroes are inserted in the vacated bits
|
||||
regardless of the sign of [x].
|
||||
The result is unspecified if [y < 0] or [y >= bitsize]. *)
|
||||
|
||||
val ( asr ) : t -> int -> t
|
||||
(** [x asr y] shifts [x] to the right by [y] bits.
|
||||
This is an arithmetic shift: the sign bit of [x] is replicated
|
||||
and inserted in the vacated bits.
|
||||
The result is unspecified if [y < 0] or [y >= bitsize]. *)
|
||||
|
||||
module Infix : sig
|
||||
val (+) : t -> t -> t
|
||||
val (-) : t -> t -> t
|
||||
val (~-) : t -> t
|
||||
val ( * ) : t -> t -> t
|
||||
val (/) : t -> t -> t
|
||||
val (mod) : t -> t -> t
|
||||
val (land) : t -> t -> t
|
||||
val (lor) : t -> t -> t
|
||||
val (lxor) : t -> t -> t
|
||||
val lnot : t -> t
|
||||
val (lsl) : t -> int -> t
|
||||
val (lsr) : t -> int -> t
|
||||
val (asr) : t -> int -> t
|
||||
val (=) : t -> t -> bool
|
||||
val (<>) : t -> t -> bool
|
||||
val (>) : t -> t -> bool
|
||||
val (>=) : t -> t -> bool
|
||||
val (<=) : t -> t -> bool
|
||||
val (<) : t -> t -> bool
|
||||
end
|
||||
val max : t -> t -> t
|
||||
(** [max x y] returns the maximum of the two integers [x] and [y].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val hash : t -> int
|
||||
(** Like {!Stdlib.abs (to_int x)}. *)
|
||||
(** [hash x] computes the hash of [x].
|
||||
Like {!Stdlib.abs (to_int x)}. *)
|
||||
|
||||
val sign : t -> int
|
||||
(** [sign x] return [0] if [x = 0], [-1] if [x < 0] and [1] if [x > 0].
|
||||
Same as [compare x zero].
|
||||
@since NEXT_RELEASE*)
|
||||
|
||||
val pow : t -> t -> t
|
||||
(** [pow base exponent] returns [base] raised to the power of [exponent].
|
||||
[pow x y = x^y] for positive integers [x] and [y].
|
||||
Raises [Invalid_argument] if [x = y = 0] or [y] < 0.
|
||||
@since 0.11 *)
|
||||
|
||||
val floor_div : t -> t -> t
|
||||
(** [floor_div x n] is integer division rounding towards negative infinity.
|
||||
It satisfies [x = m * floor_div x n + rem x n].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
type 'a printer = Format.formatter -> 'a -> unit
|
||||
type 'a random_gen = Random.State.t -> 'a
|
||||
type 'a iter = ('a -> unit) -> unit
|
||||
|
||||
|
||||
val range_by : step:t -> t -> t -> t iter
|
||||
(** [range_by ~step i j] iterates on integers from [i] to [j] included,
|
||||
where the difference between successive elements is [step].
|
||||
Use a negative [step] for a decreasing list.
|
||||
@raise Invalid_argument if [step=0].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val range : t -> t -> t iter
|
||||
(** [range i j] iterates on integers from [i] to [j] included . It works
|
||||
both for decreasing and increasing ranges.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val range' : t -> t -> t iter
|
||||
(** [range' i j] is like {!range} but the second bound [j] is excluded.
|
||||
For instance [range' 0 5 = Iter.of_list [0;1;2;3;4]].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val random : t -> t random_gen
|
||||
val random_small : t random_gen
|
||||
val random_range : t -> t -> t random_gen
|
||||
|
||||
|
||||
(** {2 Conversion} *)
|
||||
|
||||
val to_int : t -> int
|
||||
(** Convert the given native integer (type [nativeint]) to an
|
||||
integer (type [int]). The high-order bit is lost
|
||||
during the conversion. *)
|
||||
val of_string : string -> t option
|
||||
(** [of_string s] is the safe version of {!of_string_exn}.
|
||||
Like {!of_string_exn}, but return [None] instead of raising. *)
|
||||
|
||||
val of_int : int -> t
|
||||
(** Alias to {!Nativeint.of_int}.
|
||||
Convert the given integer (type [int]) to a native integer (type [nativeint]). *)
|
||||
|
||||
val to_float : t -> float
|
||||
(** Convert the given native integer to a floating-point number. *)
|
||||
|
||||
val of_float : float -> t
|
||||
(** Alias to {!Nativeint.of_float}.
|
||||
Convert the given floating-point number to a native integer,
|
||||
discarding the fractional part (truncate towards 0).
|
||||
The result of the conversion is undefined if, after truncation, the number
|
||||
is outside the range \[{!CCNativeint.min_int}, {!CCNativeint.max_int}\]. *)
|
||||
|
||||
val to_string : t -> string
|
||||
(** Return the string representation of its argument, in decimal. *)
|
||||
val of_string_opt : string -> t option
|
||||
(** [of_string_opt s] is an alias to {!of_string}. *)
|
||||
|
||||
val of_string_exn : string -> t
|
||||
(** Alias to {!Nativeint.of_string}.
|
||||
(** [of_string_exn s] converts the given string [s] into a native integer.
|
||||
Alias to {!Nativeint.of_string}.
|
||||
Convert the given string to a native integer.
|
||||
The string is read in decimal (by default, or if the string
|
||||
begins with [0u]) or in hexadecimal, octal or binary if the
|
||||
|
|
@ -136,9 +99,102 @@ val of_string_exn : string -> t
|
|||
a valid representation of an integer, or if the integer represented
|
||||
exceeds the range of integers representable in type [nativeint]. *)
|
||||
|
||||
val of_string : string -> t option
|
||||
(** Safe version of {!of_string_exn}.
|
||||
Like {!of_string_exn}, but return [None] instead of raising. *)
|
||||
val to_string_binary : t -> string
|
||||
(** [to_string_binary x] returns the string representation of the integer [x], in binary.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val of_string_opt : string -> t option
|
||||
(** Alias to {!of_string}. *)
|
||||
|
||||
(** {2 Printing} *)
|
||||
|
||||
val pp : t printer
|
||||
(** [pp ppf x] prints the integer [x] on [ppf].
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val pp_binary : t printer
|
||||
(** [pp_binary ppf x] prints [x] on [ppf].
|
||||
Print as "0b00101010".
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
|
||||
(** {2 Infix Operators} *)
|
||||
|
||||
module Infix : sig
|
||||
val ( + ) : t -> t -> t
|
||||
(** [x + y] is the sum of [x] and [y].
|
||||
Addition. *)
|
||||
|
||||
val ( - ) : t -> t -> t
|
||||
(** [x - y] is the difference of [x] and [y].
|
||||
Subtraction. *)
|
||||
|
||||
val ( ~- ) : t -> t
|
||||
(** [~- x] is the negation of [x].
|
||||
Unary negation. *)
|
||||
|
||||
val ( * ) : t -> t -> t
|
||||
(** [ x * y] is the product of [x] and [y].
|
||||
Multiplication. *)
|
||||
|
||||
val ( / ) : t -> t -> t
|
||||
(** [x / y] is the integer quotient of [x] and [y].
|
||||
Integer division. Raise [Division_by_zero] if the second
|
||||
argument [y] is zero. This division rounds the real quotient of
|
||||
its arguments towards zero, as specified for {!Stdlib.(/)}. *)
|
||||
|
||||
val ( mod ) : t -> t -> t
|
||||
(** [x mod y] is the integer remainder of [x / y].
|
||||
If [y <> zero], the result of [x mod y] satisfies the following properties:
|
||||
[zero <= x mod y < abs y] and
|
||||
[x = ((x / y) * y) + (x mod y)].
|
||||
If [y = 0], [x mod y] raises [Division_by_zero]. *)
|
||||
|
||||
val ( ** ) : t -> t -> t
|
||||
(** Alias to {!pow}
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val (--) : t -> t -> t iter
|
||||
(** Alias to {!range}.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val (--^) : t -> t -> t iter
|
||||
(** Alias to {!range'}.
|
||||
@since NEXT_RELEASE *)
|
||||
|
||||
val ( land ) : t -> t -> t
|
||||
(** [x land y] is the bitwise logical and of [x] and [y]. *)
|
||||
|
||||
val ( lor ) : t -> t -> t
|
||||
(** [x lor y] is the bitwise logical or of [x] and [y]. *)
|
||||
|
||||
val ( lxor ) : t -> t -> t
|
||||
(** [x lxor y] is the bitwise logical exclusive or of [x] and [y]. *)
|
||||
|
||||
val lnot : t -> t
|
||||
(** [lnot x] is the bitwise logical negation of [x] (the bits of [x] are inverted). *)
|
||||
|
||||
val ( lsl ) : t -> int -> t
|
||||
(** [ x lsl y] shifts [x] to the left by [y] bits.
|
||||
The result is unspecified if [y < 0] or [y >= bitsize], where [bitsize] is [32] on a 32-bit platform
|
||||
and [64] on a 64-bit platform. *)
|
||||
|
||||
val ( lsr ) : t -> int -> t
|
||||
(** [x lsr y] shifts [x] to the right by [y] bits.
|
||||
This is a logical shift: zeroes are inserted in the vacated bits
|
||||
regardless of the sign of [x].
|
||||
The result is unspecified if [y < 0] or [y >= bitsize]. *)
|
||||
|
||||
val ( asr ) : t -> int -> t
|
||||
(** [x asr y] shifts [x] to the right by [y] bits.
|
||||
This is an arithmetic shift: the sign bit of [x] is replicated
|
||||
and inserted in the vacated bits.
|
||||
The result is unspecified if [y < 0] or [y >= bitsize]. *)
|
||||
|
||||
val (=) : t -> t -> bool
|
||||
val (<>) : t -> t -> bool
|
||||
val (>) : t -> t -> bool
|
||||
val (>=) : t -> t -> bool
|
||||
val (<=) : t -> t -> bool
|
||||
val (<) : t -> t -> bool
|
||||
end
|
||||
|
||||
include module type of Infix
|
||||
|
|
|
|||
|
|
@ -6,7 +6,8 @@
|
|||
|
||||
(rule
|
||||
(targets CCShims_.ml CCShimsList_.ml CCShimsFun_.ml CCShimsFun_.mli
|
||||
CCShimsArray_.ml CCShimsFormat_.ml CCShimsMkLet_.ml CCShimsArrayLabels_.ml)
|
||||
CCShimsArray_.ml CCShimsFormat_.ml CCShimsMkLet_.ml CCShimsArrayLabels_.ml
|
||||
CCShimsInt_.ml)
|
||||
(deps ./mkshims.exe)
|
||||
(action
|
||||
(run ./mkshims.exe)))
|
||||
|
|
|
|||
|
|
@ -150,6 +150,9 @@ let shims_let_op_post_408 =
|
|||
end[@@inline]
|
||||
"
|
||||
|
||||
let shims_int_pre_408 = ""
|
||||
let shims_int_post_408 = "include Int"
|
||||
|
||||
let () =
|
||||
C.main ~name:"mkshims" (fun c ->
|
||||
let version = C.ocaml_config_var_exn c "version" in
|
||||
|
|
@ -168,4 +171,5 @@ let () =
|
|||
write_file "CCShimsFun_.ml" (if (major, minor) >= (4,8) then shims_fun_post_408 else shims_fun_pre_408);
|
||||
write_file "CCShimsFun_.mli" (if (major, minor) >= (4,8) then shims_fun_mli_post_408 else shims_fun_mli_pre_408);
|
||||
write_file "CCShimsMkLet_.ml" (if (major, minor) >= (4,8) then shims_let_op_post_408 else shims_let_op_pre_408);
|
||||
write_file "CCShimsInt_.ml" (if (major, minor) >= (4,8) then shims_int_post_408 else shims_int_pre_408);
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue