[奇怪の东西]__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 就行了.

posted @ 2022-02-08 21:28  Arextre  阅读(287)  评论(0编辑  收藏  举报