标准库标头 <bit>(C++20)学习

news2024/11/15 7:43:00

<bit>头文件是数值库的一部分。定义用于访问、操作和处理各个位和位序列的函数。例如,有函数可以旋转位、查找连续集或已清除位的数量、查看某个数是否为 2 的整数幂、查找表示数字的最小位数等。

类型

endian

(C++20)

指示标量类型的端序
(枚举)

函数

bit_cast

(C++20)

将一个类型的对象表示重解释为另一类型的对象表示
(函数模板)

byteswap

(C++23)

反转给定整数值中的字节
(函数模板)

has_single_bit

(C++20)

检查一个数是否为 2 的整数次幂
(函数模板)

bit_ceil

(C++20)

寻找不小于给定值的最小的二的整数次幂
(函数模板)

bit_floor

(C++20)

寻找不大于给定值的最大的二的整数次幂
(函数模板)

bit_width

(C++20)

寻找表示给定值所需的最小位数
(函数模板)

rotl

(C++20)

计算逐位左旋转的结果
(函数模板)

rotr

(C++20)

计算逐位右旋转的结果
(函数模板)

countl_zero

(C++20)

从最高位起计量连续的 0 位的数量
(函数模板)

countl_one

(C++20)

从最高位起计量连续的 1 位的数量
(函数模板)

countr_zero

(C++20)

从最低位起计量连续的 0 位的数量
(函数模板)

countr_one

(C++20)

从最低位起计量连续的 1 位的数量
(函数模板)

popcount

(C++20)

计量无符号整数中为 1 的位的数量
(函数模板)

下面来看一下它的具体使用示例:

endian判断CPU的大小端序

#include <bit>
#include <iostream>

//检测处理器端序,返回值:0表大端序,1表示小端序
//小端序低位存放低地址,例如:16bit的数0x1234在小端序模式CPU内存中的存放方式(假设从地址0x2000开始存放)为
//0x2000     0x34
//0x2001     0x12
int checkCPUendian()
{
    union w
    {
        int a;
        char b;
    }c;
    c.a = 1;
    return (c.b == 1);
}


int main()
{
    if constexpr (std::endian::native == std::endian::big)
        std::cout << "大端\n";
    else if constexpr (std::endian::native == std::endian::little)
        std::cout << "小端\n";
    else
        std::cout << "混合端序\n";

    int ret = checkCPUendian();
    std::cout << "ret======" << ret << std::endl;
    if (ret)
        std::cout << "CPU为小端序\n";
    else
        std::cout << "CPU为大端序\n";
    
    return 0;
}

运行结果:

运行的时候要把编译器设置为C++20或最新的c++标准

 函数示例:

#include <bit>
#include <concepts>
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <bitset>
#include <cmath>

template <std::integral T>
void dump(T v, char term = '\n')
{
    std::cout << std::hex << std::uppercase << std::setfill('0')
        << std::setw(sizeof(T) * 2) << v << " : ";
    for (std::size_t i{}; i != sizeof(T); ++i, v >>= 8)
        std::cout << std::setw(2) << static_cast<unsigned>(T(0xFF) & v) << ' ';
    std::cout << std::dec << term;
}

static_assert(std::popcount(0xFULL) == 4);

int main()
{
    //1.bit_cast example 将一个类型的对象表示重解释为另一类型的对象表示 
    float f = std::numeric_limits<float>::infinity();
    int i = std::bit_cast<int>(f);
    std::cout << "float f = " << std::hex << f
        << "\nstd::bit_cast<int>(f) = " << std::hex << i << '\n';
    
    //2.byteswap example反转给定整数值中的字节 
    static_assert(std::byteswap('a') == 'a');
    std::cout << "U16 的 byteswap:\n";
    constexpr auto x = std::uint16_t(0xCAFE);
    dump(x);
    dump(std::byteswap(x));

    std::cout << "\nU32 的 byteswap:\n";
    constexpr auto y = std::uint32_t(0xDEADBEEFu);
    dump(y);
    dump(std::byteswap(y));

    std::cout << "\nU64 的 byteswap:\n";
    constexpr auto z = std::uint64_t{ 0x0123456789ABCDEFull };
    dump(z);
    dump(std::byteswap(z));

    //3.has_single_bit example检查一个数是否为 2 的整数次幂
    for (auto u = 0u; u != 10; ++u)
    {
        std::cout << "u = " << u << " = " << std::bitset<4>(u);
        if (std::has_single_bit(u)) // P1956R1 前为 `ispow2`
            std::cout << " = 2^" << std::log2(u) << " (为二的幂)";
        std::cout << '\n';
    }

    //4.bit_ceil example寻找不小于给定值的最小的二的整数次幂
    using bin = std::bitset<8>;
    for (unsigned x{ 0 }; x != 10; ++x)
    {
        unsigned const z = std::bit_ceil(x); // P1956R1 前为 `ceil2`
        std::cout << "bit_ceil( " << bin(x) << " ) = " << bin(z) << '\n';
    }

    //5.bit_floor example寻找不大于给定值的最大的二的整数次幂
    using bin = std::bitset<8>;
    for (unsigned x = 0; x != 10; ++x)
    {
        auto const z = std::bit_floor(x); // P1956R1 前为 `floor2`
        std::cout << "bit_floor( " << bin(x) << " ) = " << bin(z) << '\n';
    }

    //6.bit_width example寻找表示给定值所需的最小位数
    for (unsigned x{ 0 }; x != 8; ++x)
    {
        std::cout << "bit_width( "
            << std::bitset<4>{x} << " ) = "
            << std::bit_width(x) << '\n';
    }

    //7.rotl example计算逐位左旋转的结果
    std::uint8_t i7 = 0b00011101;
    std::cout << "i7          = " << std::bitset<8>(i7) << '\n';
    std::cout << "rotl(i7,0)  = " << std::bitset<8>(std::rotl(i7, 0)) << '\n';
    std::cout << "rotl(i7,1)  = " << std::bitset<8>(std::rotl(i7, 1)) << '\n';
    std::cout << "rotl(i7,4)  = " << std::bitset<8>(std::rotl(i7, 4)) << '\n';
    std::cout << "rotl(i7,9)  = " << std::bitset<8>(std::rotl(i7, 9)) << '\n';
    std::cout << "rotl(i7,-1) = " << std::bitset<8>(std::rotl(i7, -1)) << '\n';

    //8.rotr example计算逐位右旋转的结果
    std::uint8_t i8 = 0b00011101;
    std::cout << "i8          = " << std::bitset<8>(i8) << '\n';
    std::cout << "rotr(i8,0)  = " << std::bitset<8>(std::rotr(i8, 0)) << '\n';
    std::cout << "rotr(i8,1)  = " << std::bitset<8>(std::rotr(i8, 1)) << '\n';
    std::cout << "rotr(i8,9)  = " << std::bitset<8>(std::rotr(i8, 9)) << '\n';
    std::cout << "rotr(i8,-1) = " << std::bitset<8>(std::rotr(i8, -1)) << '\n';

    //9.countl_zero example从最高位起计量连续的 0 位的数量
    for (const std::uint8_t i : {0, 0b11111111, 0b11110000, 0b00011110})
        std::cout << "countl_zero( " << std::bitset<8>(i) << " ) = "
        << std::countl_zero(i) << '\n';

    //10.countl_one example从最高位起计量连续的 1 位的数量
    for (const std::uint8_t i : {0, 0b11111111, 0b01111111, 0b11100011})
        std::cout << "countl_one( " << std::bitset<8>(i) << " ) = "
        << std::countl_one(i) << '\n';

    //11.countr_zero example从最低位起计量连续的 0 位的数量
    for (const std::uint8_t i : {0, 0b11111111, 0b00011100, 0b00011101})
        std::cout << "countr_zero( " << std::bitset<8>(i) << " ) = "
        << std::countr_zero(i) << '\n';

    //12.countr_one example从最低位起计量连续的 1 位的数量
    for (const std::uint8_t i : {0, 0b11111111, 0b11111110, 0b11100011})
        std::cout << "countr_one( " << std::bitset<8>(i) << " ) = "
        << std::countr_one(i) << '\n';

    //13.popcount example计量无符号整数中为 1 的位的数量
    for (const std::uint8_t x : {0, 0b00011101, 0b11111111})
        std::cout << "popcount( " << std::bitset<8>(x) << " ) = "
        << std::popcount(x) << '\n';

    return 0;
}

运行结果:

参考

https://learn.microsoft.com/zh-cn/cpp/standard-library/bit-functions?view=msvc-170#bit_cast
https://zh.cppreference.com/w/cpp/header/bit

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2139432.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

阿里云 Quick BI使用介绍

Quick BI使用介绍 文章目录 阿里云 Quick BI使用介绍1. 创建自己的quick bi服务器2. 新建数据源3. 上传文件和 使用4. 开始分析 -选仪表盘5. 提供的图表6. 一个图表的设置使用小结 阿里云 Quick BI使用介绍 Quick BI是一款全场景数据消费式的BI平台&#xff0c;秉承全场景消费…

文学智能体——摄影皮卡丘

前言 今天尝试进行智能体创建&#xff0c;我想创建什么呢&#xff0c;旅游的话&#xff0c;除了美食那就是摄影啦&#xff0c;那我就创建个皮卡丘吧&#xff0c;就决定是你啦&#xff0c;摄影皮卡丘&#xff01; 一、创建智能体 那怎么创建一个皮卡丘呢&#xff0c;那就使用…

cc2530按键中断实现控制LED

1开启中断的步骤 1-1使能端口组的中断 IEN1 IEN2 实例 IEN2 | 0x10 //使能P1口中断 1-2 端口中断屏蔽 P0IEN和P1IEN P2IEN 实例 P1IEN |0x10&#xff1b; //使能P1_2口中断 1-3设置触发方式 PICTL 实例 PICTL |0X02 ;//P1_3到P1_2口下降沿触发 1-4设置中断优先级…

解决:Vue 中 debugger 不生效

目录 1&#xff0c;问题2&#xff0c;解决2.1&#xff0c;修改 webpack 配置2.2&#xff0c;修改浏览器设置 1&#xff0c;问题 在 Vue 项目中&#xff0c;可以使用 debugger 在浏览器中开启调试。但有时却不生效。 2&#xff0c;解决 2.1&#xff0c;修改 webpack 配置 通…

【webpack4系列】webpack构建速度和体积优化策略(五)

文章目录 速度分析&#xff1a;使用 speed-measure-webpack-plugin体积分析&#xff1a;使用webpack-bundle-analyzer使用高版本的 webpack 和 Node.js多进程/多实例构建资源并行解析可选方案使用 HappyPack 解析资源使用 thread-loader 解析资源 多进程并行压缩代码方法一&…

掌握远程管理的艺术:揭秘Python的pywinrm库

文章目录 &#x1f525; 掌握远程管理的艺术&#xff1a;揭秘Python的pywinrm库 &#x1f525;背景&#xff1a;为何选择pywinrm&#xff1f;pywinrm库简介安装pywinrm库简单库函数使用方法场景应用常见问题与解决方案总结 &#x1f525; 掌握远程管理的艺术&#xff1a;揭秘Py…

gingivitis

gingivitis 牙龈炎 1&#xff09;这个是啥不知道 2&#xff09;七叶莲片 3&#xff09;甲硝唑芬布芬胶囊 4&#xff09;盐酸左氧氟沙星胶囊 5&#xff09;纳珍 开始学习记录医生开的药。日常备药记录一下。【不要乱吃药哈】

C++ | Leetcode C++题解之第409题最长回文串

题目&#xff1a; 题解&#xff1a; class Solution { public:int longestPalindrome(string s) {unordered_map<char, int> count;int ans 0;for (char c : s)count[c];for (auto p : count) {int v p.second;ans v / 2 * 2;if (v % 2 1 and ans % 2 0)ans;}retur…

C语言进阶版第10课—qsort函数排序

文章目录 1. 回调函数2. qsort排序函数&#xff08;定义&#xff09;3. bubble冒泡函数4. qsort函数对整型数组排序5. qsort函数对字符指针数组排序6. qsort函数对结构体数组排序7. 模拟实现qsort排序函数7.1 模拟实现排序整型数组7.2 模拟实现排序结构体数组 8. 结构体访问 1.…

数据库事务中的四大问题:脏读、脏写、不可重复读与幻读详解

数据库事务中的四大问题&#xff1a;脏读、脏写、不可重复读与幻读详解 什么是脏读 定义 事务B读取数据时&#xff0c;读取到的是事务A更新之后&#xff0c;但还未提交的数据。 事务A修改了一条数据&#xff0c;但是还没有提交时&#xff0c;事务B查询到了这条未提交的数据…

火语言RPA流程组件介绍--下拉框选择

&#x1f6a9;【组件功能】&#xff1a;勾选下拉框选项 配置预览 配置说明 丨目标元素 支持T或# 默认FLOW输入项 通过自动捕获工具捕获(选择元素工具使用方法)或手动填写网页元素的css,xpath&#xff0c;指定对应网页元素作为操作目标 丨值 支持T或# 选中目标的值&#xf…

Leetcode 第 413 场周赛题解

Leetcode 第 413 场周赛题解 Leetcode 第 413 场周赛题解题目1&#xff1a;3274. 检查棋盘方格颜色是否相同思路代码复杂度分析 题目2&#xff1a;3275. 第 K 近障碍物查询思路代码复杂度分析 题目3&#xff1a;3276. 选择矩阵中单元格的最大得分思路代码复杂度分析 题目4&…

【SpringCloud】Spring Cloud 开发环境搭建与基础工程构建

目录 环境和工程搭建开发环境安装JDKJDK版本介绍JDK17安装WindowsLinux - UbuntuLinux - CentOs MySQL安装UbuntuCentOS 案例介绍需求服务拆分服务拆分原则服务拆分示例 数据准备工程搭建构建父子工程创建父工程DependencyManagement 和 DependenciesSpring Cloud版本 创建子项…

【生日视频制作】奔驰梅赛德斯大奔提车交车仪式感视频拍照AE模板修改文字软件一键生成器教程特效素材【AE模板】

生日视频制作教程奔驰梅赛德斯大奔提车交车仪式感视频拍照AE模板修改文字特效广告生成神器素材祝福玩法AE模板工程 AE模板套用改图文教程↓↓&#xff1a; 怎么如何做的【生日视频制作】奔驰梅赛德斯大奔提车交车仪式感视频拍照AE模板修改文字软件一键生成器教程特效素材【AE模…

下一代 AI 搜索:多智能体 + 系统2,解决 AI 搜索在复杂信息性能下降问题

下一代 AI 搜索&#xff1a;多智能体 系统2&#xff0c;解决 AI 搜索在复杂信息性能下降问题 AI 搜索&#xff1a;从搜索引擎到答案引擎① AI 搜索市场现状&#xff08;可跳过&#xff09;② 巨好用的 AI 工具推荐程序员的垂直搜索引擎 devv.ai ③ 多智能体 系统2&#xff0c…

易扫功能介绍

背景 之前开发扫描工具&#xff0c;在大家使用过程中提出了很多改进建议&#xff0c;其中最多的就是&#xff0c;IP地址变动&#xff0c;导致无法扫描。易扫软件系统解决了这个问题&#xff0c;同时易扫服务端&#xff0c;支持多操作系统平台安装。 系统架构 主要功能介绍 支…

字典+泛型的栈与队列+委托

字典 在System.Collections.Generic下&#xff0c;对应HashTable,添加了泛型的特性&#xff0c;性能更高更安全&#xff0c;在内存中散列排布&#xff0c;存储也是键值对。 Dictionary<键的数据类型&#xff0c;值的数据类型> 字典名new Dictionary<键的数据类型&am…

18063 圈中的游戏

### 思路 1. 创建一个循环链表表示围成一圈的 n 个人。 2. 从第一个人开始报数&#xff0c;每报到 3 的人退出圈子。 3. 重复上述过程&#xff0c;直到只剩下一个人。 4. 输出最后留下的人的编号。 ### 伪代码 1. 创建一个循环链表&#xff0c;节点表示每个人的编号。 2. 初始…

【视觉中国-注册安全分析报告-无验证方式导致安全隐患】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…

TCP Analysis Flags 之 TCP ZeroWindow

前言 默认情况下&#xff0c;Wireshark 的 TCP 解析器会跟踪每个 TCP 会话的状态&#xff0c;并在检测到问题或潜在问题时提供额外的信息。在第一次打开捕获文件时&#xff0c;会对每个 TCP 数据包进行一次分析&#xff0c;数据包按照它们在数据包列表中出现的顺序进行处理。可…