mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 11:15:31 -05:00
feat(CCInt64): add popcount operation
adapted from CCInt, but directly on int64, so it works for
Int64.{min_int/max_int}.
This commit is contained in:
parent
19c65b5472
commit
22bbe23c5a
2 changed files with 28 additions and 0 deletions
|
|
@ -11,6 +11,30 @@ let hash x = Stdlib.abs (to_int x)
|
||||||
|
|
||||||
let sign i = compare i zero
|
let sign i = compare i zero
|
||||||
|
|
||||||
|
(* see {!CCInt.popcount} for more details *)
|
||||||
|
let[@inline] popcount (b:t) : int =
|
||||||
|
let m1 = 0x5555555555555555L in
|
||||||
|
let m2 = 0x3333333333333333L in
|
||||||
|
let m4 = 0x0f0f0f0f0f0f0f0fL in
|
||||||
|
|
||||||
|
let b = sub b (logand (shift_right_logical b 1) m1) in
|
||||||
|
let b = add (logand b m2) (logand (shift_right_logical b 2) m2) in
|
||||||
|
let b = logand (add b (shift_right_logical b 4)) m4 in
|
||||||
|
let b = add b (shift_right_logical b 8) in
|
||||||
|
let b = add b (shift_right_logical b 16) in
|
||||||
|
let b = add b (shift_right_logical b 32) in
|
||||||
|
let b = logand b 0x7fL in
|
||||||
|
to_int b
|
||||||
|
|
||||||
|
(*$= & ~printer:CCInt.to_string
|
||||||
|
0 (popcount 0L)
|
||||||
|
1 (popcount 1L)
|
||||||
|
63 (popcount max_int)
|
||||||
|
1 (popcount min_int)
|
||||||
|
10 (popcount 0b1110010110110001010L)
|
||||||
|
5 (popcount 0b1101110000000000L)
|
||||||
|
*)
|
||||||
|
|
||||||
let pow a b =
|
let pow a b =
|
||||||
let rec aux acc = function
|
let rec aux acc = function
|
||||||
| 1L -> acc
|
| 1L -> acc
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,10 @@ val hash : t -> int
|
||||||
(** [hash x] computes the hash of [x].
|
(** [hash x] computes the hash of [x].
|
||||||
Like {!Stdlib.abs (to_int x)}. *)
|
Like {!Stdlib.abs (to_int x)}. *)
|
||||||
|
|
||||||
|
val popcount : t -> int
|
||||||
|
(** Number of bits set to 1.
|
||||||
|
@since NEXT_RELEASE *)
|
||||||
|
|
||||||
val sign : t -> int
|
val sign : t -> int
|
||||||
(** [sign x] return [0] if [x = 0], [-1] if [x < 0] and [1] if [x > 0].
|
(** [sign x] return [0] if [x = 0], [-1] if [x < 0] and [1] if [x > 0].
|
||||||
Same as [compare x zero].
|
Same as [compare x zero].
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue