概述
描述
Boost.Charconv 将字符缓冲区转换为数字,并将数字转换为字符缓冲区。它是一个小型库,包含两个重载函数来完成繁重的工作,以及几个支持的枚举、结构体、模板和常量,特别注重性能和跨支持的开发环境的一致性。
我为什么要关注这个库?Charconv 与区域设置无关,非分配1,非抛出,并且只需要最低 C++ 11 标准。它提供了类似于 std::printf
或 std::strtod
中的功能,并具有显著的性能提升。如果您的工具链不支持标准库 <charconv>
,也可以使用此库代替它。目前只有 GCC 11+ 和 MSVC 19.24+ 在其实现的 <charconv>
中支持整数和浮点转换。
如果您正在使用这两个编译器中的任何一个,Boost.Charconv 的性能至少与 <charconv>
相当,并且速度可能快几倍。请参阅:基准测试
1 可能发生分配的唯一边缘情况是您将字符串解析为 80 位或 128 位的 long double
或 __float128
,并且字符串长度超过 1024 字节。
支持的编译器/操作系统
Boost.Charconv 已在 Ubuntu、macOS 和 Windows 上使用以下编译器进行测试
-
GCC 5 或更高版本
-
Clang 3.8 或更高版本
-
Visual Studio 2015 (14.0) 或更高版本
在 GitHub Actions 和 Drone 上测试。
入门指南
B2
运行以下命令以克隆最新版本的 Boost 和 Charconv,准备 Boost.Build 系统以供使用,并使用 C++11 作为默认标准构建库
git clone https://github.com/boostorg/boost
cd boost
git submodule update --init
cd ..
./bootstrap
./b2 cxxstd=11
要安装开发环境,请运行
sudo ./b2 install cxxstd=11
cxxstd 的值必须至少为 11。请参阅 b2 文档 中 cxxstd
下的所有有效值。
__float128
和 std::float128_t
支持
如果使用 B2 或 CMake,构建系统将自动定义 BOOST_CHARCONV_HAS_QUADMATH
并在构建系统可以成功运行小型测试用例时链接到它。如果您正在使用其他构建系统并且希望支持这些类型,则必须定义 BOOST_CHARCONV_HAS_QUADMATH
,并链接到 libquadmath。
重要
|
libquadmath 仅在受支持的平台上可用(例如,x86、x86_64、PPC64 和 IA64 的 Linux)。 |
依赖项
此库依赖于:Boost.Assert、Boost.Config、Boost.Core,以及可选的 libquadmath(请参见上文)。
基本用法示例
用法示例
#include <boost/charconv.hpp>
const char* buffer = "42";
int v = 0;
boost::charconv::from_chars_result r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v);
assert(r.ec == std::errc());
assert(v == 42);
char buffer[64];
int v = 123456;
boost::charconv::to_chars_result r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer), v);
assert(r.ec == std::errc());
assert(!strncmp(buffer, "123456", 6)); // Strncmp returns 0 on match
API 参考
from_chars
from_chars 概述
from_chars
是一组函数,用于解析 [first, last)
中的字符串,尝试根据指定的 chars_format
(如果适用)将字符串转换为 value
。数字的解析与区域设置无关(例如,等效于“C”区域设置)。from_chars
的结果是 from_chars_result
,成功时返回 ptr == last
和 ec == std::errc()
,失败时返回 ptr
等于解析的最后一个有效字符,或者下溢/溢出时返回 last
,以及分别返回 ec == std::errc::invalid_argument
或 std::errc::result_out_of_range
。from_chars
不需要字符序列以 null 结尾。
定义
namespace boost { namespace charconv {
struct from_chars_result
{
const char* ptr;
std::errc ec;
friend constexpr bool operator==(const from_chars_result& lhs, const from_chars_result& rhs) noexcept = default;
constexpr explicit operator bool() const noexcept { return ec == std::errc{}; }
}
template <typename Integral>
BOOST_CXX14_CONSTEXPR from_chars_result from_chars(const char* first, const char* last, Integral& value, int base = 10) noexcept;
template <typename Integral>
BOOST_CXX14_CONSTEXPR from_chars_result from_chars(boost::core::string_view sv, Integral& value, int base = 10) noexcept;
BOOST_CXX14_CONSTEXPR from_chars_result from_chars<bool>(const char* first, const char* last, bool& value, int base) = delete;
template <typename Real>
from_chars_result from_chars(const char* first, const char* last, Real& value, chars_format fmt = chars_format::general) noexcept;
template <typename Real>
from_chars_result from_chars(boost::core::string_view sv, Real& value, chars_format fmt = chars_format::general) noexcept;
// See note below Usage notes for from_chars for floating point types
template <typename Real>
from_chars_result from_chars_erange(const char* first, const char* last, Real& value, chars_format fmt = chars_format::general) noexcept;
template <typename Real>
from_chars_result from_chars_erange(boost::core::string_view sv, Real& value, chars_format fmt = chars_format::general) noexcept;
}} // Namespace boost::charconv
from_chars 参数
-
first
、last
- 指向要解析的有效范围的指针 -
sv
- 要解析的有效范围的字符串视图。兼容 boost::core::string_view、std::string 和 std::string_view -
value
- 成功解析后存储输出的位置 -
base
(仅限整数) - 要使用的整数基数。必须介于 2 和 36 之间(含) -
fmt
(仅限浮点数) - 缓冲区的格式。有关说明,请参阅 chars_format 概述。
from_chars_result
-
ptr
- 从from_chars
返回时,它是一个指向与模式不匹配的第一个字符的指针,如果所有字符都已成功解析,则指向last
的指针。 -
ec
- 错误代码。from_chars
返回的值为
返回值 |
描述 |
|
成功解析 |
|
1) 将负数解析为无符号类型 2) 前导 3) 前导空格 4) 不兼容的格式(例如, |
|
1) 溢出 2) 下溢 |
-
operator==
- 比较 ptr 和 ec 的值是否相等
用法说明
from_chars 用于整数类型的用法说明
-
允许所有内置整数类型,但 bool 除外,它已被删除
-
已测试这些函数以支持
__int128
和unsigned __int128
-
使用
-std=c++14
或更高版本编译时,from_chars 用于整数类型是 constexpr-
一个已知的例外是 GCC 5,它不支持
const char*
的 constexpr 比较。
-
-
有效的字符串只能包含数字字符。前导空格不会被忽略,并将返回
std::errc::invalid_argument
。
from_chars 用于浮点类型的用法说明
-
在
std::errc::result_out_of_range
上,我们为小值(例如 1.0e-99999)返回 ±0,为大值(例如 1.0e+99999)返回 ±HUGE_VAL,以匹配std::strtod
的处理方式。这与标准存在差异,标准规定我们应该返回未修改的value
参数。-
from_chars
在 LWG 中有一个未解决的问题:https://cplusplus.github.io/LWG/lwg-active.html#3081。<charconv> 的标准不像 strtod 那样区分下溢和溢出。假设您正在编写一个 JSON 库,并且出于性能原因将std::strtod
替换为boost::charconv::from_chars
。Charconv 在某些转换时返回 std::errc::result_out_of_range。然后,您必须自己再次解析字符串,才能找出导致std::errc::result_out_of_range
的四种可能原因中的哪一种。Charconv 可以通过在整个代码库中使用boost::charconv::from_chars_erange
代替boost::charconv::from_chars
来提供该信息。通过实施与已建立的 strtod 行为匹配的 LWG 问题解决方案,我认为我们提供了正确的行为,而无需等待委员会的决定。
-
-
已测试这些函数以支持所有内置浮点类型以及 C++23 的
<stdfloat>
中的浮点类型-
Long double 可以是 64、80 或 128 位,但必须符合 IEEE 754 标准。不兼容(因此不受支持)的格式示例是
__ibm128
。 -
使用
__float128
或std::float128_t
需要使用-std=gnu++xx
进行编译并链接 GCC 的libquadmath
。使用 CMake 构建时,这将自动完成。
-
示例
基本用法
整数
const char* buffer = "42";
int v = 0;
from_chars_result r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v);
assert(r.ec == std::errc());
assert(r); // Same as above but less verbose. Added in C++26.
assert(v == 42);
std::string str_buffer (buffer);
boost::core::string_view sv(str_buffer);
int v2;
auto r2 = boost::charconv::from_chars(sv, v2);
assert(r);
assert(v2 == v);
浮点数
const char* buffer = "1.2345"
double v = 0;
auto r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v);
assert(r.ec == std::errc());
assert(r); // Same as above but less verbose. Added in C++26.
assert(v == 1.2345);
std::string str_buffer(buffer);
double v2;
auto r2 = boost::charconv::from_chars(buffer, v2);
assert(r2);
assert(v == v2);
十六进制
整数
const char* buffer = "2a";
unsigned v = 0;
auto r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v, 16);
assert(r.ec == std::errc());
assert(r); // Same as above but less verbose. Added in C++26.
assert(v == 42);
浮点数
const char* buffer = "1.3a2bp-10";
double v = 0;
auto r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v, boost::charconv::chars_format::hex);
assert(r.ec == std::errc());
assert(r); // Same as above but less verbose. Added in C++26.
assert(v == 8.0427e-18);
std::errc::invalid_argument
以下代码无效,因为正在将负值解析为无符号整数。
const char* buffer = "-123";
unsigned v = 0;
auto r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v);
assert(r.ec == std::errc::invalid_argument);
assert(!r); // Same as above but less verbose. Added in C++26.
以下代码无效,因为定点格式的浮点值不能有指数。
const char* buffer = "-1.573e-3";
double v = 0;
auto r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v, boost::charconv::chars_format::fixed);
assert(r.ec == std::errc::invalid_argument);
assert(!r); // Same as above but less verbose. Added in C++26.
注意:如果出现 std::errc::invalid_argument
,from_chars
不会修改 v
std::errc::result_out_of_range
const char* buffer = "1234";
unsigned char v = 0;
auto r = boost::charconv::from_chars(buffer, buffer + std::strlen(buffer), v);
assert(r.ec == std::errc::result_out_of_range);
assert(!r); // Same as above but less verbose. Added in C++26.
assert(v == 0)
注意:如果出现 std::errc::result_out_of_range
,from_chars
不会修改 v
to_chars
to_chars 概述
to_chars
是一组函数,尝试将 value
转换为 [first, last)
指定的字符缓冲区。to_chars
的结果是 to_chars_result
,成功时返回 ptr
等于写入字符的结尾加一,并且 ec == std::errc()
,失败时返回 std::errc::value_too_large
和 ptr == last
。to_chars
不会以 null 终止返回的字符。
定义
namespace boost { namespace charconv {
struct to_chars_result
{
char* ptr;
std::errc ec;
friend constexpr bool operator==(const to_chars_result& lhs, const to_chars_result& rhs) noexcept; = default;
constexpr explicit operator bool() const noexcept { return ec == std::errc{}; }
};
template <typename Integral>
BOOST_CHARCONV_CONSTEXPR to_chars_result to_chars(char* first, char* last, Integral value, int base = 10) noexcept;
template <typename Integral>
BOOST_CHARCONV_CONSTEXPR to_chars_result to_chars<bool>(char* first, char* last, Integral value, int base) noexcept = delete;
template <typename Real>
to_chars_result to_chars(char* first, char* last, Real value, chars_format fmt = chars_format::general, int precision) noexcept;
}} // Namespace boost::charconv
to_chars 参数
-
first, last
- 指向字符缓冲区的开头和结尾的指针 -
value
- 要解析到缓冲区的值 -
base
(仅限整数) - 要使用的整数基数。必须介于 2 和 36 之间(含) -
fmt
(仅限浮点数) - 要使用的浮点格式。有关说明,请参阅 chars_format 概述。 -
precision
(仅限浮点数) - 所需的小数位数
to_chars_result
-
ptr
- 从to_chars
返回时,成功时指向写入字符的结尾加一,失败时指向last
-
ec
- 错误代码。to_chars
返回的值为
返回值 |
描述 |
|
成功解析 |
|
1) 溢出 2) 下溢 |
-
operator==
- 比较 ptr 和 ec 的值是否相等
用法说明
to_chars 用于整数类型的用法说明
-
允许所有内置整数类型,但 bool 除外,它已被删除
-
在以下情况下,from_chars 用于整数类型是 constexpr(定义了 BOOST_CHARCONV_CONSTEXPR)
-
使用
-std=c++14
或更高版本编译 -
使用具有
__builtin_ is_constant_evaluated
的编译器
-
-
已测试这些函数以支持
__int128
和unsigned __int128
to_chars 用于浮点类型的用法说明
-
处理不同的
NaN
值时将返回以下内容-
qNaN
返回“nan” -
-qNaN
返回“-nan(ind)” -
sNaN
返回“nan(snan)” -
-sNaN
返回“-nan(snan)”
-
-
已测试这些函数以支持所有内置浮点类型以及 C++23 的
<stdfloat>
中的浮点类型-
Long double 可以是 64、80 或 128 位,但必须符合 IEEE 754 标准。不兼容(因此不受支持)的格式示例是
ibm128
。 -
使用
__float128
或std::float128_t
需要使用-std=gnu++xx
进行编译并链接 GCC 的libquadmath
。使用 CMake 构建时,这将自动完成。
-
示例
基本用法
整数
char buffer[64] {};
int v = 42;
to_chars_result r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer) - 1, v);
assert(r.ec == std::errc());
assert(!strcmp(buffer, "42")); // strcmp returns 0 on match
浮点数
char buffer[64] {};
double v = 1e300;
to_chars_result r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer) - 1, v);
assert(r.ec == std::errc());
assert(r); // Same as above but less verbose. Added in C++26.
assert(!strcmp(buffer, "1e+300"));
十六进制
整数
char buffer[64] {};
int v = 42;
to_chars_result r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer) - 1, v, 16);
assert(r.ec == std::errc());
assert(r); // Same as above but less verbose. Added in C++26.
assert(!strcmp(buffer, "2a")); // strcmp returns 0 on match
浮点数
char buffer_u[64] {};
double u = -1.08260383390082950e+20;
char buffer_v[64] {};
double v = -1.08260383390082946e+20;
to_chars(buffer_u, buffer_u + sizeof(buffer_u) - 1, u, chars_format::hex);
to_chars(buffer_v, buffer_v + sizeof(buffer_v) - 1, v, chars_format::hex);
std::cout << "U: " << buffer_u << "\nV: " << buffer_v << std::endl;
// U: -1.779a8946bb5fap+66
// V: -1.779a8946bb5f9p+66
//
// With hexfloats we can see the ULP distance between U and V is a - 9 == 1.
std::errc::value_too_large
整数
char buffer[3] {};
int v = -1234;
to_chars_result r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer) - 1, v, 16);
assert(r.ec == std::errc::value_too_large);
assert(!r); // Same as above but less verbose. Added in C++26.
浮点数
char buffer[3] {};
double v = 1.2345;
auto r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer) - 1, v);
assert(r.ec == std::errc::value_too_large);
assert(!r); // Same as above but less verbose. Added in C++26.
如果出现 std::errc::value_too_large
,则 to_chars_result.ptr 等于 last
chars_format
chars_format 概述
boost::charconv::chars_format
是一个 enum class
,用于定义 from_chars
和 to_chars
的浮点类型格式。
定义
namespace boost { namespace charconv {
enum class chars_format : unsigned
{
scientific = 1 << 0,
fixed = 1 << 1,
hex = 1 << 2,
general = fixed | scientific
};
}} // Namespace boost::charconv
格式
科学计数法格式
科学计数法格式将采用 1.3e+03
的形式。整数部分将在 0 到 9 之间(含)。小数部分和指数部分将始终出现。指数将始终至少有 2 位数字。
定点格式
定点格式将采用 2.30
或 3090
的形式。此格式不会出现指数。如果 to_chars
的精度超过类型的精度(例如 std::numeric_limits<double>::chars10
),则会在有效数字的末尾附加 0。
十六进制格式
十六进制格式将采用 1.0cp+05
的形式。整数部分始终为 0 或 1。指数将使用 p 而不是 e(基数为 10 的格式使用 e),因为 e 是有效的十六进制值。注意:每个二进制浮点数都有一个唯一的十六进制浮点数表示形式,但并非每个十六进制浮点数都有一个唯一的二进制浮点数表示形式。 这是因为 IEEE754 binary32 和 binary64 的有效位数不能被 4 整除。
十六进制浮点数用例
对于不熟悉十六进制浮点数的人来说,它们在特定情况下很有价值
-
精度控制:十六进制浮点数可以更精细地控制浮点值的精度。在十六进制表示法中,每个数字代表四位(一位十六进制),允许您通过指定一定数量的十六进制数字来直接操作数字的精度。当您需要精确控制计算所需的精度级别时,这非常有用。
-
位级表示:十六进制浮点数提供了浮点数底层位的直接表示。每个十六进制数字对应于特定的位组,使其更容易可视化和理解浮点值的内部结构。这有助于调试或分析浮点算术运算(例如,计算 ULP 距离)。
通用
通用格式将是数字的最短表示形式,采用固定格式或通用格式(例如,1234
而不是 1.234e+03
)。
限制
限制概述
<boost/charconv/limits.hpp>
的内容旨在帮助用户优化 to_chars
所需的缓冲区大小。
定义
namespace boost { namespace charconv {
template <typename T>
constexpr int limits<T>::max_chars10;
template <typename T>
constexpr int limits<T>::max_chars;
}} // Namespace boost::charconv
max_chars10
当未传递任何基数或传递基数 10 时,需要传递给 to_chars
以保证所有 T 类型值成功转换的缓冲区的最小大小。
max_chars
对于任何基数值,需要传递给 to_chars
以保证所有 T 类型值成功转换的缓冲区的最小大小。
示例
以下两个示例分别用于 max_chars10
,以使用 to_chars
优化整数类型和浮点类型的缓冲区大小。
char buffer [boost::charconv::limits<std::int32_t>::max_chars10;
auto r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer), std::numeric_limits<std::int32_t>::max());
assert(r.ec == std::errc());
assert(r); // Same as above but less verbose. Added in C++26.
assert(!strcmp(buffer, "2147483647")); // strcmp returns 0 on match
char buffer [boost::charconv::limits<float>::max_chars10;
auto r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer), std::numeric_limits<float>::max());
assert(r.ec == std::errc());
assert(r); // Same as above but less verbose. Added in C++26.
assert(!strcmp(buffer, "3.40282347e+38")); // strcmp returns 0 on match
以下示例是在二进制(基数 = 2)中使用 max_chars
序列化整数的用法。
char buffer [boost::charconv::limits<std::uint16_t>::max_chars;
auto r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer), std::numeric_limits<std::uint16_t>::max(), 2);
assert(r.ec == std::errc());
assert(r); // Same as above but less verbose. Added in C++26.
assert(!strcmp(buffer, "1111111111111111")); // strcmp returns 0 on match
基准测试
本节描述了一系列性能基准测试,这些测试将此库与标准库进行了比较,以及如何在需要时运行您自己的基准测试。
这些值是相对于 std::printf
和 std::strtoX
的性能而言的。数字越大,性能越好(例如,2.00 表示速度快两倍,0.50 表示速度慢两倍)。std::printf
和 std::strtoX
始终首先列出,因为它们将作为参考值。
如何运行基准测试
要自己运行基准测试,请导航到测试文件夹并在运行测试时定义 BOOST_CHARCONV_RUN_BENCHMARKS
。在 Linux 上使用 b2 的示例:../../../b2 cxxstd=20 toolset=gcc-13 define=BOOST_CHARCONV_RUN_BENCHMARKS STL_benchmark linkflags="-lfmt" -a release
。
此外,您还需要以下内容
-
完全支持
<charconv>
的编译器-
GCC 11 或更新版本
-
MSVC 19.24 或更新版本
-
结果
x86_64 Linux
表 1 - 4 中的数据是在 Ubuntu 23.04 上使用 x86_64 架构、GCC 13.1.0 和 libstdc++ 运行的。
浮点数
函数 | 相对性能(float / double) |
---|---|
std::printf |
1.00 / 1.00 |
Boost.lexical_cast |
0.56 / 0.49 |
Boost.spirit.karma |
1.70 / 2.62 |
std::to_chars |
4.01 / 6.03 |
Boost.Charconv.to_chars |
4.46 / 6.20 |
Google double-conversion |
1.26 / 1.91 |
{fmt} 库 |
2.52 / 3.63 |
函数 | 相对性能(float / double) |
---|---|
std::strto(f/d) |
1.00 / 1.00 |
Boost.lexical_cast |
0.33 / 0.42 |
Boost.spirit.qi |
3.17 / 4.65 |
std::from_chars |
3.23 / 5.77 |
Boost.Charconv.from_chars |
3.28 / 5.75 |
Google double-conversion |
1.16 / 1.30 |
整数
函数 | 相对性能 (uint32_t / uint64_t) |
---|---|
std::printf |
1.00 / 1.00 |
Boost.lexical_cast |
1.80 / 1.38 |
Boost.spirit.karma |
2.81 / 1.62 |
std::to_chars |
4.06 / 2.45 |
Boost.Charconv.to_chars |
4.13 / 2.48 |
{fmt} 库 |
2.88 / 2.21 |
函数 | 相对性能 (uint32_t / uint64_t) |
---|---|
std::strto(ul,ull) |
1.00 / 1.00 |
Boost.lexical_cast |
0.53 / 0.52 |
Boost.spirit.qi |
2.24 / 1.49 |
std::from_chars |
1.97 / 1.68 |
Boost.Charconv.from_chars |
2.54 / 1.78 |
x86_64 Windows
表 5 - 8 中的数据是在 Windows 11 上使用 x86_64 架构、MSVC 14.3 (V17.7.0) 运行的。
浮点数
函数 | 相对性能(float / double) |
---|---|
std::printf |
1.00 / 1.00 |
Boost.lexical_cast |
0.50 / 0.70 |
Boost.spirit.karma |
2.23 / 7.58 |
std::to_chars |
5.58 / 15.77 |
Boost.Charconv.to_chars |
5.62 / 15.26 |
函数 | 相对性能(float / double) |
---|---|
std::strto(f/d) |
1.00 / 1.00 |
Boost.lexical_cast |
0.14 / 0.20 |
Boost.spirit.qi |
2.03 / 4.58 |
std::from_chars |
1.01 / 1.23 |
Boost.Charconv.from_chars |
2.06 / 5.21 |
整数
函数 | 相对性能 (uint32_t / uint64_t) |
---|---|
std::printf |
1.00 / 1.00 |
Boost.lexical_cast |
0.68 / 0.68 |
Boost.spirit.karma |
2.75 / 1.67 |
std::to_chars |
2.75 / 2.10 |
Boost.Charconv.to_chars |
2.75 / 2.06 |
函数 | 相对性能 (uint32_t / uint64_t) |
---|---|
std::strto(ul,ull) |
1.00 / 1.00 |
Boost.lexical_cast |
0.46 / 0.39 |
Boost.spirit.qi |
1.94 / 1.63 |
std::from_chars |
2.43 / 2.18 |
Boost.Charconv.from_chars |
2.68 / 2.27 |
ARM MacOS
表 9-12 中的数据是在 MacOS Ventura 13.5.2 上使用 M1 Pro 架构、Homebrew GCC 13.2.0 和 libstdc++ 运行的。
浮点数
函数 | 相对性能(float / double) |
---|---|
std::printf |
1.00 / 1.00 |
Boost.lexical_cast |
0.58 / 0.16 |
Boost.spirit.karma |
1.39 / 1.22 |
std::to_chars |
6.78 / 6.47 |
Boost.Charconv.to_chars |
7.25 / 6.86 |
Google double-conversion |
2.26 / 2.16 |
{fmt} 库 |
3.78 / 3.38 |
函数 | 相对性能(float / double) |
---|---|
std::strto(f/d) |
1.00 / 1.00 |
Boost.lexical_cast |
0.06 / 0.06 |
Boost.spirit.qi |
1.12 / 1.06 |
std::from_chars |
1.32 / 1.65 |
Boost.Charconv.from_chars |
1.28 / 1.63 |
Google double-conversion |
0.45 / 0.32 |
整数
函数 | 相对性能 (uint32_t / uint64_t) |
---|---|
std::printf |
1.00 / 1.00 |
Boost.lexical_cast |
2.08 / 1.75 |
Boost.spirit.karma |
4.17 / 2.06 |
std::to_chars |
6.25 / 4.12 |
Boost.Charconv.to_chars |
6.25 / 4.12 |
{fmt} 库 |
5.29 / 3.47 |
函数 | 相对性能 (uint32_t / uint64_t) |
---|---|
std::strto(ul,ull) |
1.00 / 1.00 |
Boost.lexical_cast |
0.56 / 0.54 |
Boost.spirit.qi |
1.39 / 1.33 |
std::from_chars |
1.92 / 1.65 |
Boost.Charconv.from_chars |
2.27 / 1.65 |
源代码
以下论文和博客文章是该库中使用的算法的基础
-
J.R. Parker 一种通用的字符到整数的转换方法,软件:实践与经验 15 (8), 1985.
-
Junekey Jeon, 更快的整数格式化 - James Anhalt (jeaiii) 的算法
-
Junekey Jeon, Dragonbox:一种新的浮点二进制到十进制转换算法
-
Junekey Jeon, 浮点数的定点精度格式化
-
William D. Clinger, 如何精确读取浮点数, 1990
-
Daniel Lemire, 以每秒千兆字节的速度解析数字, 软件:实践与经验 51 (8), 2021.
-
Noble Mushtak, Daniel Lemire, 无需回退的快速数字解析, 软件:实践与经验(即将发表)
-
Ulf Adams, 重新审视 Ryū:printf 浮点转换, ACM 编程语言论文集第 3 卷, 2019
致谢
特别感谢以下人员(非完整名单)
-
感谢 Peter Dimov 提供技术指导并在整个开发过程中为库做出贡献。
-
感谢 Junekey Jeon 开发并回答我关于他的整数格式化、Dragonbox 和 Floff 的问题。
-
感谢 Chris Kormanyos 担任图书馆审查经理。
-
感谢 Stephan T. Lavavej 为基准测试提供了基础。
-
感谢所有审查该库并提供反馈以使其变得更好的人。
版权和许可证
本文档版权所有 2022-2023 Peter Dimov 和 Matt Borland,并根据 Boost 软件许可证 1.0 版 分发。