小智 20
是的,不.
CLZ(计数前导零)和BSR(位扫描反向)相关但不同.CLZ等于(类型位宽小于1) - BSR.CTZ(计数尾随零),也称为FFS(查找第一组)与BSF(位扫描前向)相同.
请注意,在零操作时,所有这些都是未定义的!
回答你的问题,大多数时候在x86和x86_64上,__ builtin_clz生成从31减去的BSR操作(或者你的类型宽度是什么),并且__builting_ctz生成一个BSF操作.
如果你想知道汇编程序GCC正在生成什么,最好的方法就是看.-S标志将gcc输出为给定输入生成的汇编器:
gcc -S -o test.S test.c
考虑:
unsigned int clz(unsigned int num) {
return __builtin_clz(num);
}
unsigned int ctz(unsigned int num) {
return __builtin_ctz(num);
}
Run Code Online (Sandbox Code Playgroud)
在x86上为clz gcc(-O2)生成:
bsrl %edi, %eax
xorl $31, %eax
ret
Run Code Online (Sandbox Code Playgroud)
并为ctz:
bsfl %edi, %eax
ret
Run Code Online (Sandbox Code Playgroud)
请注意,如果你真的想要bsr,而不是clz,你需要做31 - clz(对于32位整数.)这解释了XOR 31,因为x XOR 31 == 31 - x(这个身份仅适用于数字从2 ^ y - 1)所以:
num = __builtin_clz(num) ^ 31;
Run Code Online (Sandbox Code Playgroud)
产量
bsrl %edi, %eax
ret
Run Code Online (Sandbox Code Playgroud)