let string_of_size ?(fuzzy=false) sz =
let szstr i unt (cur_i, cur_unt, tl) =
let tl =
(cur_i, cur_unt) :: tl
in
i, unt, tl
in
let rec decomp_continue fup i unt acc =
if i = 0L then
(
szstr i unt acc
)
else
(
let r =
Int64.rem i 1024L
in
let q =
Int64.div i 1024L
in
decomp_start (szstr r unt acc) (fup q)
)
and decomp_start acc sz =
match sz with
| TB i ->
szstr i "TB" acc
| GB i ->
decomp_continue (fun n -> TB n) i "GB" acc
| MB i ->
decomp_continue (fun n -> GB n) i "MB" acc
| KB i ->
decomp_continue (fun n -> MB n) i "KB" acc
| B i ->
decomp_continue (fun n -> KB n) i "B" acc
in
let only_significant_unit (cur_i, cur_unt, lst) =
let significant_lst =
List.filter
(fun (i, _) -> i <> 0L)
((cur_i, cur_unt) :: lst)
in
match significant_lst with
| [] -> cur_i, cur_unt, []
| (cur_i, cur_unt) :: tl -> (cur_i, cur_unt, tl)
in
let main_i, main_unt, rem_lst =
only_significant_unit (decomp_start (0L, "B", []) sz)
in
if fuzzy then
(
let (_, rem) =
List.fold_left
(fun (div, acc) (i, _unt) ->
let acc =
acc +. ((Int64.to_float i) /. div)
in
div *. 1024.0,
acc)
(1024.0, 0.0)
rem_lst
in
Printf.sprintf "%.2f %s"
((Int64.to_float main_i) +. rem)
main_unt
)
else
(
String.concat
" "
(List.map
(fun (i, unt) -> Printf.sprintf "%Ld %s" i unt)
((main_i, main_unt) :: rem_lst))
)