mte/unikernel/duniverse/ocaml_intrinsics_kernel/src/naive_ints.ml

64 lines
1.5 KiB
OCaml
Raw Normal View History

2025-11-11 02:07:51 +01:00
module type Intlike = sig
type t
val logand : t -> t -> t
val zero : t
val one : t
val equal : t -> t -> bool
val compare : t -> t -> int
val shift_right_logical : t -> int -> t
val shift_left : t -> int -> t
val bitwidth : int
end
module Make (Int : Intlike) = struct
let least_significant_bit n = Int.logand n Int.one
let is_least_significant_bit_set n =
let lsb = least_significant_bit n in
if Int.equal lsb Int.one
then true
else if Int.equal lsb Int.zero
then false
else assert false
;;
let is_most_significant_bit_set n = if Int.compare n Int.zero < 0 then true else false
let count_trailing_zeros n =
let rec loop ~acc ~mask =
if is_least_significant_bit_set mask
then acc
else (
let mask = Int.shift_right_logical mask 1 in
let acc = acc + 1 in
loop ~mask ~acc)
in
if Int.equal n Int.zero then Int.bitwidth else loop ~acc:0 ~mask:n
;;
let count_leading_zeros n =
let rec loop ~acc ~mask =
if is_most_significant_bit_set mask
then acc
else (
let mask = Int.shift_left mask 1 in
let acc = acc + 1 in
loop ~mask ~acc)
in
if Int.equal n Int.zero then Int.bitwidth else loop ~acc:0 ~mask:n
;;
let count_set_bits n =
let rec loop ~acc ~mask =
if Int.equal mask Int.zero
then acc
else (
let acc = if is_least_significant_bit_set mask then acc + 1 else acc in
let mask = Int.shift_right_logical mask 1 in
loop ~mask ~acc)
in
loop ~acc:0 ~mask:n
;;
end