add CCInt64.{hash,hash_to_int64}

This commit is contained in:
Simon Cruanes 2022-08-22 17:48:21 +00:00
parent 4e2f9220dd
commit a3abf40bc2
2 changed files with 24 additions and 3 deletions

View file

@ -5,9 +5,25 @@ 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
(* use FNV:
https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function *)
let hash_to_int64 (n : t) =
let offset_basis = 0xcbf29ce484222325L in
let prime = 0x100000001b3L in
let h = ref offset_basis in
for k = 0 to 7 do
h := mul !h prime;
(* h := h xor (k-th bit of n) *)
h := logxor !h (logand (shift_left n (k * 8)) 0xffL)
done;
logand !h max_int
let[@inline] hash (n : t) : int =
to_int (hash_to_int64 n) land CCShims_.Stdlib.max_int
(* see {!CCInt.popcount} for more details *)
let[@inline] popcount (b : t) : int =
let m1 = 0x5555555555555555L in

View file

@ -27,8 +27,13 @@ val max : t -> t -> t
@since 3.0 *)
val hash : t -> int
(** [hash x] computes the hash of [x].
Like {!Stdlib.abs (to_int x)}. *)
(** [hash x] computes the hash of [x], a non-negative integer.
Uses FNV since NEXT_RELEASE *)
val hash_to_int64 : t -> t
(** Like {!hash} but does not truncate.
Uses FNV.
@since NEXT_RELEASE *)
val popcount : t -> int
(** Number of bits set to 1.