我正在尝试将浮点数转换为位列表。
这是我的想法:
- 读取从
float
到Int64
的所有位信息 -
mod 2
64 次,每次将0
或1
存储到列表中 - 处理否定情况(应用2的补码加1)
代码是这样的:
let convert_non_neg_64 n =
let rec collect acc i j =
if Int64.compare j (Int64.of_int 64) <> -1 then acc
else collect ((Int64.rem i (Int64.of_int 2) |> Int64.to_int)::acc) (Int64.div i (Int64.of_int 2)) (Int64.succ j)
in
collect [] n Int64.zero
let negatify l =
let rl = List.rev_map (fun x -> if x = 0 then 1 else 0) l in
let rec plus1 extra acc = function
| [] -> acc
| hd::tl when extra = 0 -> plus1 0 (hd::acc) tl
| hd::tl -> if hd = 0 then plus1 0 (1::acc) tl else plus1 1 (0::acc) tl
in
plus1 1 [] rl
let convert64 n =
let nnl = convert_non_neg_64 (Int64.abs n) in
if Int64.compare n Int64.zero <> -1 then nnl
else negatify nnl
let bits_of_float fn = Int64.bits_of_float fn |> convert64
我认为代码很好。
我的问题是有更简单的方法吗?
另外,所有这些Int64
操作都非常丑陋,有什么好方法可以简化它吗?
这就是我想出的。
let bitlist_of_float f =
let rec blist b i64 =
if b >= 64 then
[]
else
let bit =
Int64.(if logand i64 (shift_left 1L b) = 0L then 0 else 1)
in
bit :: blist (b + 1) i64
in
blist 0 (Int64.bits_of_float f)
列表的开头是最不重要的位(我认为这是做事的正确方法)。我还没有验证答案,所以可能会有一两个错误。
更新
我相信这段代码会给你浮点值的位。这就是我所说的"忠实副本"的全部含义。如果你想以某种方式修改这些位,那么你需要对它们进行更多的工作。我不确定你对他们有什么想法。