mirror of
https://gitlab.com/scemama/QCaml.git
synced 2024-12-22 20:33:36 +01:00
167 lines
4.6 KiB
OCaml
167 lines
4.6 KiB
OCaml
(** Bitstring
|
|
We define here a data type to handle bit strings efficiently. When
|
|
the bit string contains less than 64 bits, it is stored internally
|
|
in a 63-bit integer and uses bitwise instructions. When more than
|
|
63 bits are required, the =zarith= library is used to consider the
|
|
bit string as a multi-precision integer.
|
|
|
|
*)
|
|
|
|
type t
|
|
|
|
val of_int : int -> t
|
|
(** Creates a bit string from an ~int~
|
|
|
|
Bitstring.of_int 15;;
|
|
- : Bitstring.t =
|
|
++++------------------------------------------------------------
|
|
*)
|
|
|
|
val of_z : Z.t -> t
|
|
(** Creates a bit string from an ~Z.t~ multi-precision integer *)
|
|
|
|
val zero : int -> t
|
|
(** ~zero n~ creates a zero bit string with ~n~ bits *)
|
|
|
|
val is_zero : t -> bool
|
|
(** True if all the bits of the bit string are zero. *)
|
|
|
|
val numbits : t -> int
|
|
(** Returns the number of bits used to represent the bit string *)
|
|
|
|
val testbit : t -> int -> bool
|
|
(** ~testbit t n~ is true if the ~n~-th bit of the bit string ~t~ is set to ~1~
|
|
|
|
Bitstring.(testbit (of_int 15) 3);;
|
|
- : bool = true
|
|
|
|
Bitstring.(testbit (of_int 15) 4);;
|
|
- : bool = false
|
|
*)
|
|
|
|
val neg : t -> t
|
|
(** Returns the negative of the integer interpretation of the bit string *)
|
|
|
|
val shift_left : t -> int -> t
|
|
(** ~shift_left t n~ returns a new bit strings with all the bits shifted ~n~
|
|
positions to the left
|
|
|
|
Bitstring.(shift_left (of_int 15) 2);;
|
|
- : Bitstring.t =
|
|
--++++----------------------------------------------------------
|
|
*)
|
|
|
|
val shift_right : t -> int -> t
|
|
(** ~shift_right t n~ returns a new bit strings with all the bits shifted ~n~
|
|
positions to the right
|
|
|
|
Bitstring.(shift_right (of_int 15) 2);;
|
|
- : Bitstring.t =
|
|
++--------------------------------------------------------------
|
|
*)
|
|
|
|
val shift_left_one : int -> int -> t
|
|
(** shift_left_one size n~ returns a new bit strings with the ~n~-th bit set to
|
|
one. It is equivalent as shifting ~1~ by ~n~ bits to the left, ~size~ is the
|
|
total number of bits of the bit string
|
|
|
|
Bitstring.shift_left_one 32 4;;
|
|
- : Bitstring.t =
|
|
----+-----------------------------------------------------------
|
|
*)
|
|
|
|
val logor : t -> t -> t
|
|
(** Bitwise logical or
|
|
|
|
Bitstring.(logor (of_int 15) (of_int 73));;
|
|
- : Bitstring.t =
|
|
++++--+---------------------------------------------------------
|
|
*)
|
|
|
|
val logxor : t -> t -> t
|
|
(** Bitwise logical exclusive or
|
|
|
|
Bitstring.(logxor (of_int 15) (of_int 73));;
|
|
- : Bitstring.t =
|
|
-++---+---------------------------------------------------------
|
|
*)
|
|
|
|
val logand : t -> t -> t
|
|
(** Bitwise logical and
|
|
|
|
Bitstring.(logand (of_int 15) (of_int 10));;
|
|
- : Bitstring.t =
|
|
-+-+------------------------------------------------------------
|
|
*)
|
|
|
|
val lognot : t -> t
|
|
(** Bitwise logical negation *)
|
|
|
|
val plus_one : t -> t
|
|
(** Takes the integer representation of the bit string and adds one
|
|
|
|
Bitstring.(plus_one (of_int 15));;
|
|
- : Bitstring.t =
|
|
----+-----------------------------------------------------------
|
|
*)
|
|
|
|
val minus_one : t -> t
|
|
(** Takes the integer representation of the bit string and removes one
|
|
|
|
Bitstring.(minus_one (of_int 15));;
|
|
- : Bitstring.t =
|
|
-+++------------------------------------------------------------
|
|
*)
|
|
|
|
|
|
val hamdist : t -> t -> int
|
|
(** Returns the Hamming distance, i.e. the number of bits differing between two
|
|
bit strings
|
|
|
|
Bitstring.(hamdist (of_int 15) (of_int 73));;
|
|
- : int = 3
|
|
*)
|
|
|
|
val trailing_zeros : t -> int
|
|
(** Returns the number of trailing zeros in the bit string
|
|
|
|
Bitstring.(trailing_zeros (of_int 12));;
|
|
- : int = 2
|
|
*)
|
|
|
|
val popcount : t -> int
|
|
(** Returns the number of bits set to one in the bit string
|
|
|
|
Bitstring.(popcount (of_int 15));;
|
|
- : int = 4
|
|
*)
|
|
|
|
|
|
val to_list : ?accu:(int list) -> t -> int list
|
|
(** Converts a bit string into a list of integers indicating the positions where
|
|
the bits are set to ~1~. The first value for the position is not ~0~ but ~1~
|
|
|
|
Bitstring.(to_list (of_int 45));;
|
|
- : int list = [1; 3; 4; 6]
|
|
*)
|
|
|
|
val permutations : int -> int -> t list
|
|
(** ~permutations m n~ generates the list of all possible ~n~-bit strings with
|
|
~m~ bits set to ~1~. Algorithm adapted from
|
|
[[https://graphics.stanford.edu/~seander/bithacks.html#NextBitPermutation][Bit twiddling hacks]]
|
|
|
|
Bitstring.permutations 2 4;;
|
|
- : Bitstring.t list =
|
|
[++--------------------------------------------------------------;
|
|
+-+-------------------------------------------------------------;
|
|
-++-------------------------------------------------------------;
|
|
+--+------------------------------------------------------------;
|
|
-+-+------------------------------------------------------------;
|
|
--++------------------------------------------------------------]
|
|
*)
|
|
|
|
|
|
(** Printers *)
|
|
|
|
val pp : Format.formatter -> t -> unit
|