我需要帮助翻转F#中的位,就像在这个问题Reverse bits in number中所做的那样。我是F#的新手,想知道我们怎么做到这一点?
let bitreverse x =
let mutable b = 0
while x do
b >>>= 1
b|= x & 1
x >>>= 1
b
我甚至不确定这里的语法是否正确。我非常了解这种语言。
答案 0 :(得分:4)
直接翻译成F#看起来像这样:
let bitreverse x =
let mutable x = x
let mutable b = 0
while x <> 0 do
b <- b <<< 1
b <- b ||| (x &&& 1)
x <- x >>> 1
b
这对于可变值非常重要,这通常不是我们在F#中编写代码的方式。请注意,重新分配可变变量与您在命令式语言中使用的变量略有不同,您必须使用称为破坏性更新运算符的<-
。
值得庆幸的是,将它转换为使用不可变值的递归函数非常简单,这些值应该更加惯用
let bitreverse2 x =
let rec bitRerverseHelper b x =
match x with
|0 -> b // if 0, the recursion stops here and we return the result: b
|_ -> bitRerverseHelper ((b <<< 1) ||| (x &&& 1)) (x >>> 1) // otherwise recurse
bitRerverseHelper 0 x
答案 1 :(得分:3)
b |= x & 1
之类的操作,需要将其展开为b <- b ||| (x &&& 1)
。x
不可变,因此您需要创建一个本地绑定并对其进行变异。它看起来很奇怪,但你可以写let mutable x = x
作为函数的第一行,用可变的阴影来遮蔽现有的绑定。x
是一个int,而不是bool,因此您不能将它用作while循环的条件。请改用x <> 0
。while
和您的最终b
都与第一个let
对齐。修复这些问题会使你的代码工作,但惯用的F#可能会放弃while
循环和变异,而是使用带累加器的递归内部函数。