Source file popcount.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
open! Import
external int_popcount : int -> int = "Base_int_math_int_popcount" [@@noalloc]
let int64_popcount =
let open Stdlib.Int64 in
let ( + ) = add in
let ( - ) = sub in
let ( * ) = mul in
let ( lsr ) = shift_right_logical in
let ( land ) = logand in
let m1 = 0x5555555555555555L in
let m2 = 0x3333333333333333L in
let m4 = 0x0f0f0f0f0f0f0f0fL in
let h01 = 0x0101010101010101L in
fun [@inline] x ->
let x = x - ((x lsr 1) land m1) in
let x = (x land m2) + ((x lsr 2) land m2) in
let x = (x + (x lsr 4)) land m4 in
to_int ((x * h01) lsr 56)
;;
let int32_popcount =
let mask = 0xffff_ffffL in
fun [@inline] x -> int64_popcount (Stdlib.Int64.logand (Stdlib.Int64.of_int32 x) mask)
;;
let nativeint_popcount =
match Stdlib.Nativeint.size with
| 32 -> fun [@inline] x -> int32_popcount (Stdlib.Nativeint.to_int32 x)
| 64 -> fun [@inline] x -> int64_popcount (Stdlib.Int64.of_nativeint x)
| _ -> assert false
;;