From b249adf86f1e84a23bbfb7af9cce4f25ccf8f147 Mon Sep 17 00:00:00 2001 From: Simon Cruanes Date: Sun, 18 Sep 2016 10:33:35 +0200 Subject: [PATCH] add `CCInt.{print_binary,to_string_binary}` + tests (thanks @gsg) --- AUTHORS.adoc | 1 + src/core/CCInt.ml | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/core/CCInt.mli | 7 +++++++ 3 files changed, 52 insertions(+) diff --git a/AUTHORS.adoc b/AUTHORS.adoc index be70282a..478c46aa 100644 --- a/AUTHORS.adoc +++ b/AUTHORS.adoc @@ -14,3 +14,4 @@ - JP Rodi - octachron (Florian Angeletti) - Johannes Kloos +- Geoff Gole (@gsg) diff --git a/src/core/CCInt.ml b/src/core/CCInt.ml index ba1d82a2..16012426 100644 --- a/src/core/CCInt.ml +++ b/src/core/CCInt.ml @@ -48,12 +48,56 @@ let random_range i j st = i + random (j-i) st let pp buf = Printf.bprintf buf "%d" let print fmt = Format.pp_print_int fmt +let most_significant_bit = + (-1) lxor ((-1) lsr 1) + let to_string = string_of_int let of_string s = try Some (int_of_string s) with _ -> None +type output = char -> unit + +(* abstract printer *) +let to_binary_gen (out:output) n = + let n = if n<0 then (out '-'; -n) else n in + out '0'; out 'b'; + let rec loop started bit n = + if bit = 0 then ( + if not started then out '0' + ) else ( + let b = n land bit in + if b = 0 then ( + if started then out '0'; + loop started (bit lsr 1) n + ) else ( + out '1'; + loop true (bit lsr 1) n + ) + ) + in + loop false most_significant_bit n + +let print_binary out n = + to_binary_gen (Format.pp_print_char out) n + +let to_string_binary n = + let buf = Buffer.create 16 in + to_binary_gen (Buffer.add_char buf) n; + Buffer.contents buf + +(*$= & ~printer:CCFun.id + "0b111" (to_string_binary 7) + "-0b111" (to_string_binary (-7)) + "0b0" (to_string_binary 0) +*) + + +(*$Q & ~count:10_000 + Q.int (fun n -> n = int_of_string (to_string_binary n)) +*) + module Infix = struct let (=) = Pervasives.(=) let (<>) = Pervasives.(<>) diff --git a/src/core/CCInt.mli b/src/core/CCInt.mli index adc77339..c6b116d9 100644 --- a/src/core/CCInt.mli +++ b/src/core/CCInt.mli @@ -40,6 +40,13 @@ val to_string : t -> string val of_string : string -> t option (** @since 0.13 *) +val print_binary : t formatter +(** prints as "0b00101010". + @since NEXT_RELEASE *) + +val to_string_binary : t -> string +(** @since NEXT_RELEASE *) + val min : t -> t -> t (** @since 0.17 *)