C 两位运算的等价性

C 两位运算的等价性,c,bit-manipulation,integer-arithmetic,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; } 我的问题是:为什么它们是等价的?对于将其转换为f的g有哪些规则/转换?1a。表达式x&-x是一种众所周知的“位破解”:它

以下两个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;
}

我的问题是:为什么它们是等价的?对于将其转换为
f
g
有哪些规则/转换?

1a。表达式
x&-x
是一种众所周知的“位破解”:它的计算结果是一个值,该值将所有位设置为
0
,除了一位:
x
原始值中最低的
1
位。(当然,除非
x
0
。)

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

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


1b。表达式
(x+1)和~x
是一种众所周知的“位破解”:它计算所有设置为
0
的位,除了
x
原始值中最低的
0
位之外。
x
中最低的
0
位成为结果值中唯一的
1
。(当然,除非
x
是全1位。)

例如,在无符号算术中:
(5+1)和-5=2
(4+1)和-4=1

2b。表达式
x-1
x
中的所有尾随
0
位替换为
1
,并将
x
中的最低
1
位替换为
0
,保持
x
的其余部分不变。运算符
&
组合所有
0
位(就像运算符
组合所有
1
位一样)。这意味着
(A-1)和(B-1)
将具有最低的
0
位,其中最低的
1
位位于
A
B

3b。每1b,
(C+1)和~C
将最低的
0
替换为一个
1
,将其他所有内容归零

这意味着
g
做的事情与
f
做的事情相同。这两个函数都查找并返回两个输入值之间的最低
1
位。结果总是2的幂(或仅为0)。例如,如果至少有一个输入值为奇数,则结果为1



我有一种直觉(这可能是错误的),为了通过对现有表达式应用附加操作来构建一个函数到另一个函数的正式转换,至少需要其中一个函数是“可逆的”(这是该术语的一些半非正式含义)。这两个函数在我看来都不够“可逆”…

如果两个逻辑函数具有相同的真值表(使它们相等),这并不意味着将一个函数转换为另一个函数的规则存在。此外,它们可以使用不同的代数(运算符集)。还要注意,这些不是按位函数,因为它们包含算术运算符。我不认为它们是等价的,假设A是5,B是4,从fn中f将返回0,而fn g将返回非零值。@Bas,这种情况下,从f和g中都返回1。哦,对不起,我接受了-(A | B)as~(A | B)@chux:Good point。我最初假设一元
-
在无符号值中产生的位模式取决于表示形式。但它不是。Minor:“…在a和B中最低1的位置包含唯一的1位。”-->“a或B中最低1。”。这里使用的英语意义上的“and”与
A | B
操作有些冲突。嗯,甚至我的建议看起来都很尴尬。