C++23 引入了可选的扩展浮点类型,包括
std::float16_t
、 std::float32_t
、 std::float64_t
、 std::float128_t
和 std::bfloat16_t
。这些类型为开发者提供了更灵活的浮点数选择,尤其是在高性能计算和机器学习领域。
1. 扩展浮点类型概述
传统上,C++ 提供了三种浮点类型:float
(32 位)、double
(64 位)和 long double
(通常是 80 位或 128 位)。然而,随着计算架构的多样化和对更高性能的需求,C++23 引入了更多浮点类型。
std::float16_t
:16 位浮点数,遵循 IEEE 754 标准的binary16
格式,具有 1 位符号位、5 位指数位和 11 位尾数位。std::bfloat16_t
:16 位浮点数,由 TensorFlow 和现代 TPU 支持,格式为 1 位符号位、8 位指数位和 7 位尾数位。它与 32 位浮点数的转换非常简单,且在机器学习中具有更高的性能。std::float32_t
、std::float64_t
和std::float128_t
:分别对应 32 位、64 位和 128 位浮点数,遵循 IEEE 754 标准。
2. 如何使用这些类型
这些扩展浮点类型通过 <stdfloat>
头文件提供,并且每个类型都有对应的字面量后缀。例如:
#include <stdfloat>
auto a = 1.0f16; // std::float16_t
auto b = 1.0bf16; // std::bfloat16_t
auto c = 1.0f32; // std::float32_t
auto d = 1.0f64; // std::float64_t
auto e = 1.0f128; // std::float128_t
这些后缀是大小写不敏感的,但需要注意 bf16
和 BF16
是有效的,而 Bf16
或 bF16
是无效的。
3. 编译器支持
目前,GCC 13 已经支持这些扩展浮点类型。然而,Clang 尚未完全支持,而 MSVC 仅提供了空的 <stdfloat>
文件,尚未实现任何扩展浮点类型。
4. 特性测试宏
为了检测编译器是否支持这些扩展浮点类型,C++23 提供了以下特性测试宏:
__STDCPP_FLOAT16_T__
__STDCPP_FLOAT32_T__
__STDCPP_FLOAT64_T__
__STDCPP_FLOAT128_T__
__STDCPP_BFLOAT16_T__
这些宏的值为1
,表示对应的类型被支持。
5. 类型转换和重载决议
扩展浮点类型之间的转换遵循一定的规则:
std::float16_t
和std::bfloat16_t
之间无法隐式转换。std::float16_t
和std::bfloat16_t
都可以隐式转换为更高的浮点类型,如std::float32_t
或std::float64_t
。long double
的转换序数始终大于double
和std::float64_t
。
在函数重载决议中,如果存在多个隐式转换,优先选择不改变转换序数的类型。如果所有选择都需要改变转换序数,则会导致二义性。
6. 标准库支持
C++23 还为这些扩展浮点类型提供了标准库支持,包括:
std::numeric_limits
和std::is_floating_point
的特化。std::to_chars
和std::from_chars
的重载。- IOStreams 库的输入输出操作符重载。
<cmath>
中的数学函数重载。std::complex
和std::atomic
的重载。
7. 应用场景
这些扩展浮点类型特别适用于高性能计算和机器学习领域。例如:
- 在机器学习中,
std::bfloat16_t
提供了更高的计算效率和更小的存储需求。 - 在需要更高精度的科学计算中,
std::float128_t
可以提供更精确的结果。
8. 总结
C++23 的扩展浮点类型为开发者提供了更灵活的选择,尤其是在高性能计算和机器学习领域。通过这些新类型,开发者可以更好地优化程序的性能和存储需求。然而,需要注意的是,这些类型的编译器支持仍在不断完善中。