【问题标题】:Using AND bitwise operator between a number, and its negative counterpart在数字与其负数之间使用 AND 按位运算符
【发布时间】:2023-01-12 04:46:53
【问题描述】:

我偶然发现了这行简单的代码,但我无法弄清楚它的作用。我理解它在不同部分的作用,但我并不真正理解它的整体。

// We have an integer(32 bit signed) called i
// The following code snippet is inside a for loop declaration
// in place of a simple incrementor like i++ 
// for(;;HERE){}
i += (i&(-i))

如果我理解正确的话,它在 i 和负 i 之间使用 AND 二元运算符,然后将该数字添加到 i。我首先认为这将是一种计算整数绝对值的优化方法,但是据我所知,c++ 不会简单地通过翻转一点来存储负整数,但如果我错了请纠正我。

【问题讨论】:

  • 这是您自己探索的好机会。编写一个程序,循环打印出 i(i&(-i)) 以查看值是什么。找出值的二进制表示(手动或使用程序)以找到模式
  • c ++不会简单地通过翻转位来存储负整数. AFAIK C23 要求对负整数值使用二进制补码。
  • 您需要指定您要求的语言(您同时标记了 C 和 C++)和版本。关于整数表示的规则在不同语言或版本之间不一定相同。
  • 您询问绝对值:使用二进制补码整数,它可以实现为 (x + (x >> N)) ^ (x >> N),其中 N 是位 -1 中类型的大小。
  • 如果 iINT_MIN,此代码将调用 UB

标签: c++ c integer bit bitwise-and


【解决方案1】:

假设二进制补码表示,并假设i不是INT_MIN,表达式i & -i导致i中设置的最低位的值。

如果我们针对 i 的各种值查看此表达式的值:

 0 00000000: i&(-i) = 0
 1 00000001: i&(-i) = 1
 2 00000010: i&(-i) = 2
 3 00000011: i&(-i) = 1
 4 00000100: i&(-i) = 4
 5 00000101: i&(-i) = 1
 6 00000110: i&(-i) = 2
 7 00000111: i&(-i) = 1
 8 00001000: i&(-i) = 8
 9 00001001: i&(-i) = 1
10 00001010: i&(-i) = 2
11 00001011: i&(-i) = 1
12 00001100: i&(-i) = 4
13 00001101: i&(-i) = 1
14 00001110: i&(-i) = 2
15 00001111: i&(-i) = 1
16 00010000: i&(-i) = 16

我们可以看到这种模式。

将其外推到 i += (i&(-i)),假设 i 为正,它将最低设置位的值添加到 i。对于 2 的幂的值,这只是将数字加倍。

对于其他值,它将数字向上舍入该最低位的值。在循环中重复此操作,最终得到 2 的幂。至于这样的增量可以用于什么,这取决于使用此表达式的上下文。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-11
    • 2016-07-18
    • 2019-05-20
    相关资源
    最近更新 更多