【发布时间】: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 中将是一个正数。