【问题标题】:Bit manipulation with Erlang's bitwise bnot operator使用 Erlang 的按位 bnot 运算符进行位操作
【发布时间】:2016-12-23 10:48:34
【问题描述】:

阅读chapter 2 Hacker's Delight 并尝试在 Erlang 中实现位操作。

我被这个卡住了:

使用以下公式创建一个单词,在 x 中尾随 1 的位置为 0,在其他位置为 1,如果没有,则生成所有 1(例如 10100111 => 11111000):

          ¬ x | (x + 1)

这是我尝试过的:

(bnot X) bor (X + 2#01)

但由于某种原因,结果是-1000,而不是2#11111000。

奇怪的是not 2#10100111 是-10101000(基数为2)。

知道发生了什么吗?

【问题讨论】:

  • -1000 可能与 2#11111000 相同,具体取决于我的阅读方式。你能确认它确实不同吗?
  • Erlang 不限制整数的大小,所以符号位没有固定的位置。就像正数有一个无限的前缀零一样,负数被视为有一个无限的前缀。所以,bnot 2#0001 是 2#...1110(-2,二进制补码),bnot 2#0010 是 2#...1101(-3 二进制补码)等等。通过用 2 屏蔽(带) bsl (W-1) - 1,你可以将结果截断为W位的正数。
  • @RichardC 你能把这个变成答案吗?你的意思是2#...1101 是-4 吗?因为101 是 4?还是我误会了什么?
  • 下面@pascal 的答案是正确的,我只是想澄清发生了什么。例如。 2#101 是 5(不是 4),但在二进制补码中,-5 如果限制为 8 位,则为 11111011(反转正数并加 1)。在 Erlang 中,只要你有一个负整数,你就必须想象左边有无数个 1。如果你用“band 2#11111111”屏蔽它,你将只保留低 8 位,这在 Erlang 中将是一个正数。

标签: erlang bit-manipulation


【解决方案1】:

你必须限制被操纵的数字的宽度(符号问题、bignum 和整数表示问题)。

下一个示例使用 8 位,但它与 128 位的工作方式相同,在这种情况下,您的测试用例的结果将是 340282366920938463463374607431768211448 而不是 248。

1> Msk = fun(X) -> X band 2#11111111 end. % limit to 8 bits
#Fun<erl_eval.6.52032458>
2> Op = fun(X) -> Msk(bnot(X)) bor Msk(X+1) end.
#Fun<erl_eval.6.52032458>
3> Op(2#10100111).
248
4> 2#11111000.
248

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-30
    • 2012-02-11
    相关资源
    最近更新 更多