C++20 `<bit>` 中的整数 2 的幂运算和 `std::bit_cast`:由浅入深的探索

举报
码事漫谈 发表于 2025/03/13 18:47:17 2025/03/13
【摘要】 引言 1. 整数 2 的幂运算 1.1 检测是否为 2 的幂:std::has_single_bit 1.2 计算不小于 x 的最小 2 的幂:std::bit_ceil 1.3 计算不大于 x 的最大 2 的幂:std::bit_floor 2. std::bit_cast 2.1 基本用法 2.2 实用场景:字节序列与结构体之间的转换 3. 总结 引言C++20 引入了 <bit> 头...

寻找特定比例男程序员图片.png

引言

C++20 引入了 <bit> 头文件,为开发者提供了丰富的位操作功能,极大地简化了底层编程的复杂性。其中,整数 2 的幂运算和 std::bit_cast 是两个非常实用的功能。本文将通过示例代码,由浅入深地介绍它们的用法和应用场景。


1. 整数 2 的幂运算

C++20 在 <bit> 中提供了多个与整数 2 的幂相关的函数,例如 std::has_single_bitstd::bit_ceilstd::bit_floor。这些函数可以帮助开发者高效地处理与 2 的幂相关的运算。

1.1 检测是否为 2 的幂:std::has_single_bit

std::has_single_bit 函数用于检测一个整数是否为 2 的幂。如果一个整数的二进制表示中只有一个位为 1,则该数为 2 的幂。

#include <iostream>
#include <bit>

int main() {
    for (unsigned int i = 0; i < 10; ++i) {
        if (std::has_single_bit(i)) {
            std::cout << i << " 是 2 的幂" << std::endl;
        } else {
            std::cout << i << " 不是 2 的幂" << std::endl;
        }
    }
    return 0;
}

输出示例:

0 不是 2 的幂
12 的幂
22 的幂
3 不是 2 的幂
42 的幂
5 不是 2 的幂
6 不是 2 的幂
7 不是 2 的幂
82 的幂
9 不是 2 的幂

1.2 计算不小于 x 的最小 2 的幂:std::bit_ceil

std::bit_ceil 函数用于计算不小于给定整数的最小 2 的幂。例如,std::bit_ceil(5) 的结果是 8,因为 8 是不小于 5 的最小 2 的幂。

#include <iostream>
#include <bit>
#include <bitset>

int main() {
    for (unsigned int i = 0; i < 10; ++i) {
        auto result = std::bit_ceil(i);
        std::cout << "bit_ceil(" << i << ") = " << result << std::endl;
    }
    return 0;
}

输出示例:

bit_ceil(0) = 0
bit_ceil(1) = 1
bit_ceil(2) = 2
bit_ceil(3) = 4
bit_ceil(4) = 4
bit_ceil(5) = 8
bit_ceil(6) = 8
bit_ceil(7) = 8
bit_ceil(8) = 8
bit_ceil(9) = 16

1.3 计算不大于 x 的最大 2 的幂:std::bit_floor

std::bit_floor 函数用于计算不大于给定整数的最大 2 的幂。例如,std::bit_floor(5) 的结果是 4。

#include <iostream>
#include <bit>
#include <bitset>

int main() {
    for (unsigned int i = 0; i < 10; ++i) {
        auto result = std::bit_floor(i);
        std::cout << "bit_floor(" << i << ") = " << result << std::endl;
    }
    return 0;
}

输出示例:

bit_floor(0) = 0
bit_floor(1) = 1
bit_floor(2) = 2
bit_floor(3) = 2
bit_floor(4) = 4
bit_floor(5) = 4
bit_floor(6) = 4
bit_floor(7) = 4
bit_floor(8) = 8
bit_floor(9) = 8

2. std::bit_cast

std::bit_cast 是 C++20 中引入的一种类型转换方式,它允许开发者在不同类型的位模式之间进行无损转换。与传统的 reinterpret_cast 不同,std::bit_cast 更安全,因为它不会改变对象的值,而是直接复制位模式。

2.1 基本用法

std::bit_cast 的语法如下:

template <class To, class From>
constexpr To bit_cast(const From& src) noexcept;

以下是一个将浮点数转换为整数的示例:

#include <iostream>
#include <bit>

int main() {
    double f = 123.456;
    auto u = std::bit_cast<uint64_t>(f);

    std::cout << "bit_cast<uint64_t>(" << f << ") = 0x" << std::hex << u << std::endl;

    auto f2 = std::bit_cast<double>(u);
    std::cout << "bit_cast<double>(0x" << std::hex << u << ") = " << f2 << std::endl;

    return 0;
}

输出示例:

bit_cast<uint64_t>(123.456) = 0x405ed4ccccccccd
bit_cast<double>(0x405ed4ccccccccd) = 123.456

2.2 实用场景:字节序列与结构体之间的转换

std::bit_cast 还可以用于将字节序列转换为结构体,这对于处理二进制文件或网络数据非常有用。例如:

#include <iostream>
#include <bit>
#include <array>

struct Vec3 {
    float x, y, z;
};

int main() {
    std::array<uint8_t, sizeof(Vec3)> buffer = {0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
    Vec3 vec = std::bit_cast<Vec3>(buffer);

    std::cout << "Vec3: (" << vec.x << ", " << vec.y << ", " << vec.z << ")" << std::endl;

    return 0;
}

输出示例:

Vec3: (1.000000, 0.000000, 0.000000)

3. 总结

C++20 的 <bit> 头文件为开发者提供了强大的位操作功能,其中整数 2 的幂运算和 std::bit_cast 是两个非常实用的工具。通过本文的示例,你可以快速掌握它们的用法,并将其应用于实际项目中。无论是处理底层数据结构,还是进行高效的位运算,这些功能都能显著提升你的开发效率。

希望本文对你有所帮助!如果有任何问题或建议,欢迎在评论区留言讨论。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。