循环遍历位(Bits)C
问题的出现原因:
作者想要通过循环遍历一个字中的所有设置位(即为1的位),但是对于给定的位数i,作者希望找到下一个设置位的位置。
解决方法:
作者给出了一个函数next_bit,它通过使用位运算和一些数学操作来找到下一个设置位的位置。具体来说,该函数首先使用位与运算和位取反运算来清除位i之前的所有位,然后利用ctz函数来计算位i之后的下一个设置位的位置。ctz函数是一个计算末尾零位数的内建函数,作者给出了在gcc和llvm上使用的具体实现。
这个方法可能在无符号字符上有些过于复杂,对于8位字来说,使用一个简单的while循环可能更好。
作者提到,他正在寻找一种使用最少的CPU周期的方法来解决这个问题,并且询问这种方法是否比掩码或移位方法使用更多的周期。
循环遍历位(Looping through Bits C)这个问题的出现的原因是希望按位遍历一个字节中的每一位,并根据位的值执行相应的操作。解决方法是使用一个循环来遍历每一位,并使用位运算来判断位的值。
具体的代码如下:
unsigned char somebyte = ...; for (int i = 0; i < 8; ++i, somebyte >>= 1) { if (somebyte & 0x1) { // Do stuff for 1 bit } else { // Do stuff for 0 bit } }
这段代码从最低位到最高位逐位遍历了一个字节。在每一次循环中,使用位运算`somebyte & 0x1`来判断最低位的值是0还是1。如果最低位为1,则执行相应的操作;如果最低位为0,则执行其他操作。然后,通过右移运算符`somebyte >>= 1`将字节中的下一位移到最低位,以便在下一次循环中判断。
然而,上述代码只是一个通用的用例,实际上更常见的情况是并行化处理(一次操作整个字节)或仅对1位进行操作(并在运行完所有8次循环之前结束循环)。要解决具体的问题,需要更多的上下文信息。可以参考位操作技巧网站来寻找更高效的解决方案。
循环遍历位可以通过以下几种方式实现:
- 您可以使用破坏性循环,通过移位操作并测试初始或最终位来枚举位的顺序,或
- 您可以使用按位与运算符测试数字与由左移操作符
1
产生的单比特掩码。
下面是第一种方法的示例:
unsigned int bits = ...; while (bits) { if (bits & 1) { // 当前位为1 } else { // 当前位为0 } bits >>= 1; }
如果在达到零后仍然想继续处理位,请创建一个单独的计数器。
下面是第二种方法的示例:
unsigned int bits = ...; for (int pos = 0 ; pos != 16 ; pos++) { if (bits & (1 << pos)) { // 当前位为1 } else { // 当前位为0 } }
如果在最后一个1位之后的0位上需要执行操作,则第一个示例是无效的,因为它在bits
为0时停止。
这是一个合理的观点-我已经向问题的提问者提到了这一点,谢谢!