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
      (
        
        (** Continue with upper unit *)

        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 =
    (* Decompose size for current unit and try
     * to use upper unit
     *)

    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
      
  (* Only accumulate significant unit in tail *)
  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))
      )