【问题标题】:Reversing Bits in F#在 F# 中反转位
【发布时间】:2016-05-20 20:48:10
【问题描述】:

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

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

我什至不确定这里的语法是否正确。我非常熟悉这种语言。

【问题讨论】:

  • 欢迎来到 StackOverflow!请展示您尝试过的内容以及具体无效的内容。

标签: f# bits


【解决方案1】:

直接翻译成 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# 中编写代码的方式。请注意,可变变量的重新分配与您在命令式语言中可能习惯的略有不同,您必须使用称为破坏性更新运算符的&lt;-

谢天谢地,将其转换为使用不可变值的递归函数非常简单,这应该更符合习惯

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

【讨论】:

  • 只是好奇,还有比这更短的反转位的方法吗?
  • @user112901 您可以使用if 代替模式匹配将逻辑放在一行中,例如let rec bitRerverseHelper b x = if x = 0 then b else bitRerverseHelper ((b &lt;&lt;&lt; 1) ||| (x &amp;&amp;&amp; 1)) (x &gt;&gt;&gt; 1)。我发现模式匹配更容易阅读。
  • 我的意思是有另一种完全不同的方法来反转 F# 中的位吗?像内置函数,或任何其他可能比这个逻辑更简单/更短的逻辑?
  • @user112901 不是内置的,没有。尽管在 C:stackoverflow.com/a/746203/5438433 中进行了描述,但此答案对一些可能的方法进行了非常全面的概述,因此对于小于 int. 的数据类型,您当然可以缩短
【解决方案2】:
  1. F#不支持复合赋值,所以不能做b |= x &amp; 1之类的事情,需要将其扩展为b &lt;- b ||| (x &amp;&amp;&amp; 1)
  2. 参数x 不是可变的,因此您需要创建一个本地绑定并对其进行修改。它看起来很奇怪,但您可以将 let mutable x = x 作为函数的第一行来使用可变绑定来隐藏现有绑定。
  3. x 是 int,而不是 bool,因此您不能将其用作 while 循环的条件。请改用x &lt;&gt; 0
  4. 缩进在 F# 中很重要,因此请确保 while 和最后的 b 都与第一个 let 对齐。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-03-12
    • 1970-01-01
    • 2021-12-16
    • 2020-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多