(** 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