在 F# 中反转位

Reversing Bits in F#

我需要帮助来反转 F# 中的位,就像在这个问题 Reverse bits in number 中所做的那样。我是 F# 的新手,想知道我们如何做到这一点?

let bitreverse x = 
   let mutable b = 0
       while x do 
          b >>>= 1
          b|= x & 1
          x >>>= 1
b

我什至不确定这里的语法是否正确。我对这门语言非常了解。

  1. F#不支持复合赋值,所以不能做b |= x & 1,需要扩展成b <- b ||| (x &&& 1).
  2. 参数 x 不可变,因此您需要创建本地绑定并对其进行修改。看起来很奇怪,但您可以将 let mutable x = x 写为函数的第一行,以使用可变绑定来隐藏现有绑定。
  3. x 是一个整数,而不是一个布尔值,因此您不能将它用作 while 循环的条件。请改用 x <> 0
  4. F# 中的缩进很重要,因此请确保 while 和最后的 b 都与第一个 let.
  5. 对齐

解决这些问题将使您的代码正常工作,但惯用的 F# 可能会放弃 while 循环和变异,而是使用带累加器的递归内部函数。

直接翻译成 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