c - 等效于两个按位运算

标签 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

最佳答案

1a。表达式x & -x是一个众所周知的“位hack”:它的值等于除一位以外的所有位均设置为0的值:原始值1中的最低x位。 (当然,除非x0。)
例如,在无符号算术中:5 & -5 = 14 & -4 = 4等。
2a。这立即告诉我们f的功能:通过使用|运算符,它将1A中的所有B位组合在一起,然后在组合值中找到最低的1。换句话说,f的结果是一个单词,该单词在11的最低A位置中包含唯一的B位。

1b。表达式(x + 1) & ~x是一个众所周知的“位hack”:它计算设置为0的所有位,除了0原始值中的最低x位。在结果值中,0中的最低x位变为唯一的1。 (当然,除非x为全1位。)
例如,在无符号算术中:(5 + 1) & -5 = 2(4 + 1) & -4 = 1等。
2b。表达式x - 10替换x中的所有尾随1位,并用1替换x中的最低0,而其余x保持不变。运算符&组合所有0位(就像运算符|组合所有1位一样)。这意味着(A - 1) & (B - 1)将具有其最低的0位,而最低的1位在AB中。
3b。每1b,(C + 1) & ~C用一个单独的0替换最低的1,将其他所有内容清零。
这意味着g的作用与f相同。这两个函数都查找并返回两个输入值之间的最低1位。结果始终是2的幂(或仅为0)。例如。如果至少一个输入值是奇数,则结果为1。

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

关于c - 等效于两个按位运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25279002/

相关文章:

c - 如何通过fscanf找到EOF?

c - 在 C 控制台应用程序 (unix) 中更新屏幕行

java - 16位偏移和24位偏移是什么意思?我如何使用java进行这样的计算

c - C 中的 Bitboard 国际象棋编程

java - Java 中复合赋值(+=、-=、*=、...)的混淆

python - Numpy/Python : why is integer division slowest? 中基本数学运算的速度

c - 汇编语言到 C

将ucs(通用字符集)字符转换为unicode?

c - 身份属性的位操作

检查有符号加法和阿贝尔群中的溢出