[奇怪の东西]__builtin函数
记录一些 __builtin
开头的函数。
-
__builtin_ffs(x)
返回 \(x\) 最后一个 \(1\) 是向前几位,而__builtin_ffs(x) - 1
就是 \(x\) 最后一个为 \(1\) 的位置是 \(2\) 的几次方; -
__builtin_clz(x)
返回 \(x\) 二进制下前导 \(0\) 的个数;
其代码实现:
int __builtin_clzl(unsigned long x) {
int r = 0;
if (!(x & 0xFFFFFFFF00000000)) r += 32, x <<= 32;
if (!(x & 0xFFFF000000000000)) r += 16, x <<= 16;
if (!(x & 0xFF00000000000000)) r += 8, x <<= 8;
if (!(x & 0xF000000000000000)) r += 4, x <<= 4;
if (!(x & 0xC000000000000000)) r += 2, x <<= 2;
if (!(x & 0x8000000000000000)) r += 1, x <<= 1;
return r;
}
__builtin_ctz(x)
返回 \(x\) 二进制下末尾 \(0\) 的个数;
代码实现:
int __builtin_ctzl(unsigned long x) {
int r = 63;
x &= ~x + 1;
if (x & 0x00000000FFFFFFFF) r -= 32;
if (x & 0x0000FFFF0000FFFF) r -= 16;
if (x & 0x00FF00FF00FF00FF) r -= 8;
if (x & 0x0F0F0F0F0F0F0F0F) r -= 4;
if (x & 0x3333333333333333) r -= 2;
if (x & 0x5555555555555555) r -= 1;
return r;
}
__builtin_parity(x)
返回 \(x\) 中 \(1\) 数量的奇偶性;__builtin_popcount(x)
返回 \(x\) 中 \(1\) 的数量;
代码实现:
int __builtin_popcountl(unsigned long x) {
x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555);
x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333);
x = (x & 0x0F0F0F0F0F0F0F0F) + (x >> 4 & 0x0F0F0F0F0F0F0F0F);
x = (x & 0x00FF00FF00FF00FF) + (x >> 8 & 0x00FF00FF00FF00FF);
x = (x & 0x0000FFFF0000FFFF) + (x >> 16 & 0x0000FFFF0000FFFF);
x = (x & 0x00000000FFFFFFFF) + (x >> 32 & 0x00000000FFFFFFFF);
return x;
}
上述函数都有对应的 long long
形式,在后面加 ll
就行了.