【问题标题】:Left rotation bitwise operation in Elixir/why is the signed left shift missing?Elixir中的左旋转按位运算/为什么缺少带符号的左移?
【发布时间】:2015-12-22 18:49:35
【问题描述】:

免责声明:对于按位运算,我非常幼稚,因此很感谢您降低操作。

我基本上是尝试在 Elixir 中执行左旋转,基于我正在使用的一些等效 Java(我需要移植一小块)。

public static long rotateLeft(long l, int shift) {
    return (l << shift) | l >>> (64 - shift);
}

通常我不会对我的工作内容如此直言不讳,但我相信它是相关的,因为使用了 &lt;&lt; 运算符(在 Elixir/Erlang 中似乎不存在) .

是否有一些明显的方法可以在 Elixir 中复制我缺少的上述行为?我已经搜索了没有运算符的实现,但似乎大多数其他语言都有它,所以它没有出现在任何地方。确实出现的一件事是X &lt;&lt; Y == X * 2 * Y,所以我是这样实现的:

def rotate_left(l, shift) when is_number(l) and is_number(shift) do
    (l * 2 * shift) ||| l >>> (64 - shift)
end

但是,通过两种语言 (rotate_left(2461839666708829781, 13)) 运行测试会在每种语言中提供不同的结果 - 所以我想我犯了一个错误。

如果有人可以伸出援手/解释我在这里遗漏了什么(我认为这个运算符不存在是有原因的),我们将不胜感激。我试图涵盖所有内容,以防由于特定数字等原因,但如果我错过了任何重要的事情,请告诉我。

还有;如果 Elixir 无法实现,我非常乐意使用 Erlang。提前致谢!

【问题讨论】:

    标签: bit-manipulation bitwise-operators elixir


    【解决方案1】:

    你想使用the Bitwise module:

    iex(1)> use Bitwise
    nil
    iex(2)> 3 <<< 8 ||| 3 >>> (64 - 8)
    768
    

    【讨论】:

    • &lt;&lt;&lt; 是否等同于 &lt;&lt;?
    • 是的,除了在 Elixir 和 Erlang 中,整数是任意精度的,因此值是否超过可以容纳的最大 64 位无关紧要。因此,您将获得与 Java 或 C/C++ 不同的结果。您可以使用按位与将结果限制为 64 位:((val &lt;&lt;&lt; shift) ||| (val &gt;&gt;&gt; (64 - shift))) &amp;&amp;&amp; 0xFFFFFFFFFFFFFFFF。
    • 谢谢!一段时间以来,我一直在用头撞精度。你能准确总结一下 AND 是如何限制位的吗?
    • 十六进制值0xFFFFFFFFFFFFFFFF 大小为 64 位,由全 1 组成。对某个值执行按位运算意味着该值中适合 64 位的所有位都被保留,而超过 64 位的值的任何位都有效地与 0 进行按位与运算,因此它们也变为 0 和因此被丢弃。
    • 听起来很完美。这是 NIF 的一大用途——它小巧、专注且简单,但仍可为您的应用程序提供可衡量的价值。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    • 2012-05-31
    • 1970-01-01
    • 2019-12-04
    • 1970-01-01
    相关资源
    最近更新 更多