前导零计数
计算一个 32位 数头部 0 的个数。例如 1 前面有 31 个0, 0 则前面有 32 个0。
C 语言实现
int cntLeadingZeros(uint32_t i)
{
int ret = 0;
uint32_t temp = ~i;
while(temp & 0x80000000)
{
temp <<= 1;
ret++;
}
return ret;
}
硬件指令
在 ARM 和 Xtensa 架构的硬件中,具有单独的指令可以完成前导0计算。
在 ARM 下是 clz
指令; 在 Xtensa 下是 NSAU
指令,用法一样。
内嵌汇编实现
int cntLeadingZeros(uint32_t i)
{
int ret = 0;
__asm("clz %0, %1 ": "=r"(i) : "r"(ret)); //arm
__asm("nsau %0, %1 ": "=r"(i) : "r"(ret)); //xtensa
return ret;
}