求解一个数的二进制最高位
求解一个数的二进制最高位是一个常见问题。具体来说,5 的二进制是 101,其最高位在第 2 位(假定最低位是0)。30 的二进制是 11110,最高位是第 4 位。我们怎么求解这个位数呢?
方案一:逐位遍历
从低位向高位逐渐遍历即可,无需解释。当然也有很多种写法。这里提供一种。
int highestBit(int num) { if (num == 0) return 0; int pos = 0; while (num > 1) { num >>= 1; pos++; } return pos; }
方案二:部分打表
还有一个思路是空间换时间,对小范围的数据打表。假如我们首先计算出 lookup[256]
表示 0-255各自的最高位位置。由于 int 可以划分成8位为一块进行处理,我们先检查高16位是否有值,若有则只考虑高 16 位,否则只考虑低 16 位。同理再划分一次,我们则可以将范围缩小到 8 位,调用计算好的结果即可。
const int lookup[256] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 }; int highestBit(int num) { if (num == 0) return 0; int pos = 0; if (num & 0xFFFF0000) { pos += 16; num >>= 16; } if (num & 0xFF00) { pos += 8; num >>= 8; } return pos + lookup[num]; }
方案三:内置函数
在 C+ 中,GCC 和 Clang 编译器提供了一个内置函数 __builtin_clz
,用于计算一个整数的前导零的数量。结合这个函数,可以快速找到一个整数的最高位1的位置。
#include <climits> // for CHAR_BIT int highestBit(int num) { if (num == 0) return 0; return sizeof(num) * CHAR_BIT - 1 - __builtin_clz(num); }
__builtin_clz(num)
:返回整数 num
的前导零的数量。sizeof(num) * CHAR_BIT
:表示整数 num
的总位数。例如,对于32位整数,这个值是32。相减再减一就是正确答案。
使用 __builtin_clz
的效率通常非常高,这是因为它通常会被编译器翻译成一条高效的汇编指令。例如,在x86架构上,它通常被翻译成一条BSR(Bit Scan Reverse)或LZCNT(Leading Zero Count)指令,这些指令在硬件级别上非常高效。
大多数现代CPU都支持相关指令,在其他编译器(如MSVC)上可能需要不同的方法。可自行查阅。
注意处理负数
由于补码的性质,负数不存在最高位1。如果一定要定义一个,那么就是第31位(即表示符号的最高位),上面的函数均没有考虑负数情况,请多加注意。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步