C++ 高效位运算函数 之 __builtin_

本文介绍了五个位操作函数:ffs用于查找二进制最低位1的位置;popcount统计二进制中1的数量;ctz计算最低位连续0的个数;clz统计前导0的个数;parity判断1的个数的奇偶性。通过具体示例展示了每个函数的功能及应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.int ffs(ui x){//该函数判断n的二进制末尾最后一个1的位置,从一开始
    return __builtin_ffs(x);
}


2.int popcount(ui x){//该函数时判断n的二进制中有多少个1
    return __builtin_popcount(x);
}


3.int ctz(ui x){//该函数判断n的二进制末尾后面0的个数,当x为0时,和x的类型有关
    return __builtin_ctz(x);
}


4.int clz(ui x){//x前导0的个数。x=0时和x的类型有关
    return __builtin_clz(x);
}


5.int parity(ui x){//该函数是判断n的二进制中1的个数的奇偶性
    return __builtin_parity(x);
}

#include<bits/stdc++.h>
using namespace std;
typedef unsigned int ui;
int ffs(ui x){//该函数判断n的二进制末尾最后一个1的位置,从一开始
	return __builtin_ffs(x);
}
int popcount(ui x){//该函数时判断n的二进制中有多少个1
	return __builtin_popcount(x);
}
int ctz(ui x){//该函数判断n的二进制末尾后面0的个数,当n为0时,和n的类型有关
	return __builtin_ctz(x);
}
int clz(ui x){//x前导0的个数。x=0时结果未定义。
	return __builtin_clz(x);
}
int parity(ui x){//该函数是判断n的二进制中1的个数的奇偶性
	return __builtin_parity(x);
}
int main(){
	cout<<"__builtin_ffs : "<<endl;
	cout<<ffs(1)<<endl;//1二进制1   /输出1 
	cout<<ffs(8)<<endl;//8二进制1000   /输出4 
	//要是要输出最后一个一的位置应当-1
	
	cout<<"__builtin_popcount : "<<endl;
	cout<<popcount(15)<<endl;//1111  /输出4
	
	cout<<"__builtin_ctz :"<<endl;
	cout<<ctz(8)<<endl;//1000 /输出3
	
	cout<<"__builtin_clz :"<<endl;
	cout<<clz(8)<<endl;//...1000 /输出28 
	 
	cout<<"__builtin_parity :"<<endl;
	cout<<parity(15)<<endl;//1111 /偶数个,输出0
	cout<<parity(7)<<endl;//111 /奇数个,输出1 
	
	return 0;
} 

 

<think>好的,我需要解释C++中的__builtin_popcount()函数。首先,这个函数是GCC编译器提供的一个内建函数,用于计算一个整数二进制表示中1的个数,也就是“population count”或“汉明重量”。用户可能想知道它的用途、参数、返回值以及注意事项。 首先,函数的作用。它统计无符号整数的二进制中1的数量。例如,0b1011会返回3。需要提到它属于编译器扩展,可能不是跨平台的,只在GCC和兼容的编译器中可用。 接下来,参数类型。不同的版本处理不同位数的整数:__builtin_popcount(unsigned int)用于32位,__builtin_popcountll(unsigned long long)用于64位。这点需要明确区分,避免用户误用导致错误。 然后,头文件的问题。虽然通常不需要包含特定头文件,但可能在某些情况下需要包含<stdlib.h>或<limits>,不过一般来说编译器内置函数可以直接使用。 示例代码部分,应该给出简单明了的例子,比如用unsigned int和unsigned long long的变量演示函数调用和输出结果。这样用户能直观地看到效果。 注意事项方面,要强调可移植性问题,如果用户需要跨编译器,可能需要改用C++标准库中的std::bitset<N>::count()或者C++20的std::popcount()。此外,提示内建函数通常经过高度优化,效率高,适合性能敏感的场景。 最后,对比其他方法,比如手动循环或查表法,说明内建函数的优势。这样用户能理解在何时选择使用这个函数。 需要确保整个解释结构清晰,步骤分明,用中文口语化表达,避免技术术语堆砌,同时覆盖所有关键点。检查是否有遗漏的信息,比如不同数据类型的处理,或者常见错误情况。确保示例代码正确,并符合C++语法规范。同时,提醒用户注意编译器兼容性,避免他们在其他环境下遇到问题。</think>好的,我来逐步解释 C++ 中的 `__builtin_popcount()` 函数: 1. **功能作用** `__builtin_popcount()` 是 GCC 编译器提供的内建函数,用于计算一个**无符号整数**的二进制表示中 `1` 的个数。例如: - `0b1011` ➔ 返回 `3`(因为有3个1) - `0x0F` (二进制 `00001111`) ➔ 返回 `4` 2. **参数与返回值** - **参数类型**:接受 `unsigned int`(32位)或 `unsigned long long`(64位) - **返回值**:`int` 类型,表示1的个数 - **变体**: - `__builtin_popcount()` ➔ 处理 `unsigned int` - `__builtin_popcountll()` ➔ 处理 `unsigned long long` 3. **代码示例** ```cpp #include <iostream> using namespace std; int main() { unsigned int a = 0b1101; // 二进制 1101,十进制13 cout << __builtin_popcount(a) << endl; // 输出3 unsigned long long b = 0xFF; // 二进制 11111111 cout << __builtin_popcountll(b) << endl; // 输出8 return 0; } ``` 4. **注意事项** - **编译器依赖**:仅适用于 GCC 和 Clang 等兼容编译器,MSVC 不可用 - **可移植替代方案**: ```cpp // C++20 标准方法 #include <bit> std::popcount(0x0Fu); // C++11 的 bitset #include <bitset> std::bitset<32>(num).count(); ``` 5. **性能优势** 该函数会编译为底层硬件指令(如 x86 的 `POPCNT`),比手动位运算(如循环移位+计数)快得多,适合高频调用场景。 6. **典型应用场景** - 位掩码统计(如棋盘游戏、状态压缩) - 汉明距离计算 - 二进制图像处理(如像素密度统计)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值