两个按位运算的等价性

时间:2014-08-13 05:57:31

标签: c bit-manipulation integer-arithmetic

以下两个C函数是等效的:

unsigned f(unsigned A, unsigned B) {
  return (A | B) & -(A | B);
}
unsigned g(unsigned A, unsigned B) {
  unsigned C = (A - 1) & (B - 1);
  return (C + 1) & ~C;
}

我的问题是:为什么它们相同? g将哪些规则/转换转换为f

1 个答案:

答案 0 :(得分:7)

<强> 1A 即可。表达式x & -x是一个众所周知的&#34; bit hack&#34;它评估为一个值,所有位都设置为0,除了一位:最低1位在x的原始值中。 (当然,除非x0。)

例如,在无符号算术中:5 & -5 = 14 & -4 = 4等。

<强> 2A 即可。这会立即告诉我们f函数的作用:通过使用|运算符,它会合并1A中的所有B位,然后找到最低1在组合值中。换句话说,f的结果是在11中最低A位置包含唯一B位的字词。< / p>


<强>图1b 即可。表达式(x + 1) & ~x是一个众所周知的&#34; bit hack&#34;它评估为设置为0的所有位,除了{{{}的原始值中的最低0位。 1}}。 x中的最低0位成为结果值中唯一的x。 (当然,除非1全是1位。)

例如,在无符号算术中:x(5 + 1) & -5 = 2等。

<强> 2B 即可。表达式(4 + 1) & -4 = 1x - 1中的所有尾随0位替换为x,并将1中的1替换为x,并保留0 x的其余部分没有变化。运算符&组合了所有0位(就像运算符|组合了所有1位)。这意味着(A - 1) & (B - 1)的最低0位将位于1A中最低的B位。

<强> 3B 即可。每1b,(C + 1) & ~C将最低0替换为孤独1,将其他所有内容归零。

这意味着gf的功能相同。两个函数都查找并返回两个输入值之间的最低1位。结果总是2的幂(或只是0)。例如。如果至少有一个输入值是奇数,则结果为1.


我有一种直觉(可能是错误的),为了通过对现有表达式应用附加操作来构建一个函数到另一个函数的正式转换,需要至少其中一个函数为#34可逆&#34; (是该术语的一些半非正式含义)。这两者中的任何一个都看起来不够充分&#34;可逆&#34;给我......