作用
返回 x 的二进制下后导的 0 的个数,
ctz(count trailing zero) 计算后导 0,和 __builtin_clz 相对
int __builtin_ctz (unsigned int x)
Returns the number of trailing 0-bits in x, starting at the least significant bit position. If x is 0, the result is undefined.
int __builtin_ctzl (unsigned long x)
Similar to __builtin_ctz, except the argument type is unsigned long.
int __builtin_ctzll (unsigned long long x)
Similar to __builtin_ctz, except the argument type is unsigned long long.
例如
int n = 1;//1
int m = 8;//1000
__builtin_ctzll(n) /* 结果为 0 */
__builtin_ctz(m) /* 结果为 3 */
ARM 上实现
unsigned int __builtin_ctz(unsigned int x) {
unsigned int count;
asm ("rbit %0, %1\n\t"
"clz %0, %0" : "=r" (count) : "r" (x));
return count;
}
这段代码使用了汇编语言内联(inline assembly)来实现 __builtin_ctz 函数。以下是对代码的详细解释:
-
asm 关键字: asm 关键字用于在C代码中嵌入汇编语言代码。
-
`“rbit %0, %1\n\t” :这是一个汇编指令,使用 rbit 指令将输入值 x 的位序反转。 %0 和 %1 是占位符,分别表示输出和输入操作数。
rbit 是按位反转的, 相当于把 32位 整数的二进制表示法水平旋转 180 度
-
“clz %0, %0” :这是另一个汇编指令,使用 clz 指令计算反转后的值中前导零的数量。 %0 表示输入和输出操作数,因为反转后的值在此时已经存储在了 %0 中。
-
: “=r” (count) : “r” (x) :这是约束(constraint)部分,用于指定操作数的寄存器约束。 “=r” (count) 表示将 count 变量的值存储到一个通用寄存器中,并且该寄存器在指令执行后作为输出。 “r” (x) 表示将 x 变量的值存储到另一个通用寄存器中,并且该寄存器在指令执行前作为输入。
-
return count :将计算得到的前导零的数量作为函数的返回值。
这段代码的作用是使用ARM指令集中的 rbit 和 clz 指令来计算输入值 x`的二进制表示中末尾零的数量。通过反转位序和计算前导零的方式,可以有效地实现这一功能。请注意,这段代码的实现依赖于特定的ARM架构和编译器,具体的实现细节可能因平台和编译器的不同而有所不同。
使用示例
#include <stdio.h>
int main()
{
unsigned int x = 12; /* 0b00000000000000000000000000001100 in binary */
unsigned int count = __builtin_ctz(x);
printf("Number of trailing zeros: %u\n", count);
return 0;
}
结果输出
Number of trailing zeros: 2