Elixir中左旋转按位运算/为什么签名左移失踪?

whi*_*fin 2 bit-manipulation elixir bitwise-operators

免责声明:当谈到按位操作时,我非常天真,所以我很感激.

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

public static long rotateLeft(long l, int shift) {
    return (l << shift) | l >>> (64 - shift);
}
Run Code Online (Sandbox Code Playgroud)

通常情况下,我不会那么直率地讨论我正在做什么,但我认为由于使用了<<运算符(Elixir/Erlang中似乎不存在),因此它是相关的.

是否有一些明显的方法可以在Elixir中复制我失踪的上述行为?我已经搜索了没有运算符的实现,但似乎大多数其他语言都有它,因此它没有出现在任何地方.确实出现了一件事X << 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
Run Code Online (Sandbox Code Playgroud)

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

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

也; 如果Elixir不可能,我很高兴能够下到Erlang.提前致谢!

Ste*_*ski 7

您想使用Bitwise模块:

iex(1)> use Bitwise
nil
iex(2)> 3 <<< 8 ||| 3 >>> (64 - 8)
768
Run Code Online (Sandbox Code Playgroud)

  • 十六进制值"0xFFFFFFFFFFFFFFFF"的大小为64位,由全1组成.执行一个按位 - 并且对它有一些值意味着保留了适合64位的那个值的所有位,而延伸到64位以上的任何值的位有效地按0进行按位,因此它们也变为0并且因此被放弃了. (4认同)
  • 是的,除了在Elixir和Erlang中,整数是任意精度,因此如果值超过最大64位可以容纳则无关紧要.因此,您将获得与Java或C/C++不同的结果.您可以使用按位 - 并将结果限制为64位,并且:`((val <<< shift)|||(val >>>(64-shift)))&&& 0xFFFFFFFFFFFFFFFF`. (3认同)