C++中的位运算符

embedded/2024/10/22 12:29:36/

位运算符:

  1. 按位与 (&)

    int a = 6; // 0110 in binary
    int b = 3; // 0011 in binary
    int c = a & b; // 结果为 2 (0010),因为对应位置都为1才为1
  2. 按位或 (|)

    int a = 6;
    int b = 3;
    int c = a | b; // 结果为 7 (0111),因为任一位置有1则结果为1
  3. 按位异或 (^)

    int a = 6;
    int b = 3;
    int c = a ^ b; // 结果为 5 (0101),因为对应位置不同时结果为1
  4. 按位取反 (~)

    int a = 6;
    int c = ~a; // 结果为 -7 (…1101),对整个二进制位取反(包括符号位)
  5. 左移 (<<)

    int a = 1; // 00000001
    int b = a << 2; // 结果为 4 (00000100),a 向左移动两位
  6. 右移 (>>)

    int a = 8; // 00001000
    signed int b = a >> 1; // 结果为 4 (对于有符号数,最高位决定符号,这里是正数,所以右移后保留符号位)
    unsigned int c = a >> 1; // 对于无符号数,结果也是 4 (00000100)

特殊位运算函数:

  • C++标准库并没有内置大量的位运算函数,但某些编译器提供了扩展函数,例如:

    • __builtin_popcount():计算给定整数中“1”的个数(比特数)
    • __builtin_clz() 或 __builtin_ctz():分别计算给定整数中最高置零位的位置(从最左边开始计数,不包括符号位)或最低置位的位置(从最右边开始计数)
  • 标准库中,std::bitset 类可以用于更高级别的位操作,比如按位逻辑运算、获取和设置单个位等。

应用场景:

  • 优化程序性能位运算可以直接在硬件层面执行,因此在一些场合下它们比常规算术运算更快。
  • 布尔操作:用来模拟简单的布尔逻辑表达式
  • 掩码操作:用于访问和修改特定位,常用于网络编程、图形处理等领域。
  • 压缩数据结构:通过位字段来存储多个布尔状态,节省空间。

注意事项:

  • 位运算符的操作数通常是整型(包括但不限于intunsigned intchar等)。
  • 左移和右移可能会导致溢出,尤其是在处理有符号整数时,右移的符号扩展行为应当注意。
  • 使用位运算时应考虑数据类型的大小,特别是跨平台编程时,不同平台上整型的大小可能不同。

std::bitset的举例说明

#include <bitset>
#include <iostream>
int main() {using namespace std;// 定义一个包含16位的bitsetbitset<16> bs;// 初始化bitsetbs = bitset<16>(0xFFFF); // 全部位设为1cout << "Initialized Bitset: " << bs << endl;// 设置指定位置的位为1bs.set(3); // 第4位(从0开始计数)设为1cout << "After setting the 4th bit to 1: " << bs << endl;// 获取指定位置的位bool fourthBit = bs.test(3);cout << "The value of the 4th bit is: " << fourthBit << endl;// 按位逻辑运算bitset<16> bs1(0b10101010);bitset<16> bs2(0b11001100);bitset<16> resultAnd = bs1 & bs2; // 按位与bitset<16> resultOr = bs1 | bs2;  // 按位或bitset<16> resultXor = bs1 ^ bs2; // 按位异或// 输出bitsetcout << "Original Bitset 1: " << bs1 << endl;cout << "Original Bitset 2: " << bs2 << endl;cout << "AND Operation:     " << resultAnd << endl;cout << "OR Operation:      " << resultOr << endl;cout << "XOR Operation:     " << resultXor << endl;// 重置指定位置的位为0bs.reset(3); // 第4位设为0cout << "After resetting the 4th bit to 0: " << bs << endl;// 翻转指定位置的位bs.flip(3); // 第4位翻转(0变1,1变0)cout << "After flipping the 4th bit: " << bs << endl;// 读取bitset的字符串形式string bitString = bs.to_string(); // 得到一个包含bitset所有位的字符串形式cout << "Bitset as a string: " << bitString << endl;// 从整数初始化bitsetbitset<16> fromInt(bs.to_ulong()); // 从bs转换成的无符号长整型重新创建bitsetcout << "Recreated Bitset from integer: " << fromInt << endl;// 输出bitset大小size_t size = bs.size();cout << "Bitset size: " << size << endl;// (注:这里的cin >> bs 和 cout << bs 示例仅适用于交互式环境,在实际运行中可能无法看到效果)// 输入和输出bitset(需要重载流操作符)// cin >> bs; // 输入一个bitset// cout << bs; // 输出一个bitsetreturn 0;
}
Initialized Bitset: 1111111111111111
2After setting the 4th bit to 1: 1111111111111011
3The value of the 4th bit is: 1
4Original Bitset 1: 10101010
5Original Bitset 2: 11001100
6AND Operation:     10001000
7OR Operation:      11101110
8XOR Operation:     01100110
9After resetting the 4th bit to 0: 1111111111111001
10After flipping the 4th bit: 1111111111111011
11Bitset as a string: 1111111111111011
12Recreated Bitset from integer: 1111111111111011
13Bitset size: 16

http://www.ppmy.cn/embedded/30649.html

相关文章

停止使用 TypeScript 接口

为什么应该使用类型而不是接口 这张图片是由人工智能生成的。 类型和接口 是每个 TypeScript 程序中使用的重要特性。 然而&#xff0c;由于类型和接口在功能上非常相似&#xff0c;这就引出了一个问题&#xff1a;哪个更好&#xff1f; 今天&#xff0c;我们将评估类型和接…

YOLOv5白皮书-第Y6周:模型改进

YOLOv5白皮书-第Y6周&#xff1a;模型改进 YOLOv5白皮书-第Y6周&#xff1a;模型改进一、前言二、我的环境三、更正后的yolov5s.yaml四、运行截图![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/23c3ac6b05d74bfcbea5ec238681710d.png)五、总结 YOLOv5白皮书-第Y6周…

Angular中的管道(Pipe)

Angular中的管道(Pipe) 文章目录 Angular中的管道(Pipe)前言一、内置管道1. date管道格式化日期2. currency管道格式化货币3. uppercase和lowercase管道转换字符串大小写4. 小数位数5. JavaScript 对象序列化6. slice7. 管道链 二、自定义管道 前言 Angular中的管道&#xff0…

深度解析 Spring 源码:从BeanDefinition源码探索Bean的本质

文章目录 一、BeanDefinition 的概述1.1 BeanDefinition 的定位1.2 BeanDefition 的作用 二、BeanDefinition 源码解读2.1 BeanDefinition 接口的主要方法2.2 BeanDefinition 的实现类2.2.1 实现类的区别2.2.2 setBeanClassName()2.2.3 getDependsOn()2.2.4 setScope() 2.3 Bea…

设计模式之模板模式

模板模式&#xff08;Template Method Pattern&#xff09;是行为设计模式之一&#xff0c;它定义了一个操作中的算法骨架&#xff0c;而将一些步骤延迟到子类中实现。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤&#xff0c;从而达到复用算法框架…

学习 Rust 的第十五天:如何处理程序异常信息

大家好&#xff0c; 在过去的三天里&#xff0c;我们已经完成了 Rust 的三个常见集合&#xff0c;今天我们将学习有关 Rust 中错误处理的所有内容。 引言 错误处理基本上意味着如何处理一些对你的程序来说不是最佳选择的情况&#xff0c;有一些可以优雅处理的错误&#xff0…

spring boot 启动流程详解

主启动类 SpringBootApplication MapperScan("com.example.mapper") public class StableBootApplication {public static void main(String[] args) {SpringApplication.run(StableBootApplication.class,args);} }SpringApplication类中有个静态run()方法&#xf…

常用设计模式

单例模式 一个类只能创建一个对象&#xff0c;即单例模式&#xff0c;该设计模式可以保证系统中该类只有⼀个实例&#xff0c;并提供⼀个访问它的全局访问点&#xff0c;该实例被所有程序模块共享。比如在某个服务器程序中&#xff0c;该服务器的配置信息存放在⼀个文件中&…