Overview
Description
Charconv is a collection of parsing functions that are locale-independent, non-allocating, and non-throwing. This library requires a minimum of C++11.
Usage Examples
#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) - 1, v);
assert(r.ec == std::errc());
assert(!strncmp(buffer, "123456", 6)); // Strncmp returns 0 on match
Supported Compilers
-
GCC 5 or later
-
Clang 3.7 or later
-
Visual Studio 2015 (14.0) or later
Tested on Github Actions and Drone.
Why use Boost.Charconv over <charconv>?
Currently only GCC 11+ and MSVC 19.24+ support both integer and floating-point conversions in their implementation of <charconv>
.
If you are using either of those compilers, Boost.Charconv is at least as performant as <charconv>
, and can be up to several times faster.
See: Benchmarks
Building the Library
B2
Run the following commands to clone the latest versions of Boost and Charconv, prepare the Boost.Build system for use, and build the libraries with C++11 as the default standard:
git clone https://github.com/boostorg/boost
cd boost
git submodule update --init
cd libs
git clone https://github.com/cppalliance/charconv
cd ..
./bootstrap
./b2 cxxstd=11
To install the development environment, run:
sudo ./b2 install cxxstd=11
vcpkg
Run the following commands to clone the latest version of Charconv and install it using vcpkg:
git clone https://github.com/cppalliance/charconv
cd charconv
vcpkg install charconv --overlay-ports=ports/charconv
Any required Boost packages that do not already exist will be installed automatically.
Conan
Run the following commands to clone the latest version of Charconv and build a boost_charconv package using your default profile:
git clone https://github.com/cppalliance/charconv
conan create charconv/conan --build missing
The package will be put in the local Conan cache along with all direct and transitive dependencies.
Tip
|
Since Charconv only depends on a few header-only Boost libraries, you can save time by requesting header-only Boost: |
conan create charconv/conan -o 'boost*:header_only=True' --build missing
After the package is built, you can use it in your own projects.
For example, using a conanfile.txt
:
[requires]
boost_charconv/1.0.0
from_chars
from_chars overview
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
friend constexpr bool operator!=(const from_chars_result& lhs, const from_chars_result& rhs) noexcept
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;
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;
}} // Namespace boost::charconv
from_chars_result
-
ptr - points to the first character not matching the pattern, or has the value of last if all characters are successfully parsed.
-
ec - the error code. Valid values for are:
-
std::errc() - successful parsing
-
std::errc::invalid_argument - invalid argument (e.g. parsing a negative number into an unsigned type)
-
std::errc::result_out_of_range - result out of range (e.g. overflow)
-
-
operator== - compares the values of ptr and ec for equality
-
operator! - compares the value of ptr and ec for inequality
from_chars
-
first, last - valid range to parse
-
value - where the output is stored upon successful parsing
-
base (integer only) - the integer base to use. Must be between 2 and 36 inclusive
-
fmt (floating point only) - The format of the buffer. See chars_format overview for description.
from_chars for integral types
-
All built-in integral types are allowed except bool which is deleted
-
These functions have been tested to support
__int128
andunsigned __int128
-
from_chars for integral types is constexpr when compiled using
-std=c++14
or newer-
One known exception is GCC 5 which does not support constexpr comparison of
const char*
.
-
from_chars for floating point types
-
On std::errc::result_out_of_range we return ±0 for small values (e.g. 1.0e-99999) or ±HUGE_VAL for large values (e.g. 1.0e+99999) to match the handling of
std::strtod
. This is a divergence from the standard which states we should return thevalue
argument unmodified. -
These functions have been tested to support all built-in floating-point types and those from C++23’s
<stdfloat>
-
Long doubles can be 64, 80, or 128-bit, but must be IEEE 754 compliant. An example of a non-compliant, and therefore unsupported, format is
__ibm128
. -
Use of
__float128
orstd::float128_t
requires compiling with-std=gnu++xx
and linking GCC’slibquadmath
.
-
Examples
Basic usage
Integral
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);
Floating Point
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);
Hexadecimal
Integral
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);
Floating Point
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.
Note: In the event of std::errc::invalid_argument, v is not modified by from_chars
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)
Note: In the event of std::errc::result_out_of_range, v is not modified by from_chars
to_chars
to_chars overview
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;
friend constexpr bool operator!=(const to_chars_result& lhs, const to_chars_result& rhs) noexcept;
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_result
-
ptr - points to the first character
-
ec - the error code. Valid values from are:
-
0 - successful parsing
-
std::errc::invalid_argument - invalid argument
-
std::errc::result_out_of_range - result out of range (e.g. overflow)
-
-
operator== - compares the value of ptr and ec for equality
-
operator!= - compares the value of ptr and ec for inequality
to_chars
-
first, last - pointers to the character buffer
-
value - the value to be parsed into the buffer
-
base (integer only) - the integer base to use. Must be between 2 and 36 inclusive
-
fmt (float only) - the floating point format to use. See chars_format overview for description.
-
precision (float only) - the number of decimal places required
to_chars for integral types
-
All built-in integral types are allowed except bool which is deleted
-
from_chars for integral type is constexpr (BOOST_CHARCONV_CONSTEXPR is defined) when:
-
compiled using
-std=c++14
or newer -
using a compiler with
__builtin_ is_constant_evaluated
-
-
These functions have been tested to support
__int128
andunsigned __int128
to_chars for floating point types
-
The following will be returned when handling different values of
NaN
-
+qNaN returns "nan"
-
-qNaN returns "-nan(ind)"
-
+sNaN returns "nan(snan)"
-
-sNaN returns "-nan(snan)"
-
-
These functions have been tested to support all built-in floating-point types and those from C++23’s
<stdfloat>
-
Long doubles can be 64, 80, or 128-bit, but must be IEEE 754 compliant. An example of a non-compliant, and therefore unsupported, format is
ibm128
. -
Use of
__float128
orstd::float128_t
requires compiling with-std=gnu++xx
and linking GCC’slibquadmath
.
-
Examples
Basic Usage
Integral
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
Floating Point
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"));
Hexadecimal
Integral
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
Floating Point
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::result_out_of_range
Integral
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::result_out_of_range);
assert(!r); // Same as above but less verbose. Added in C++26.
Floating Point
char buffer[3] {};
double v = 1.2345;
auto r = boost::charconv::to_chars(buffer, buffer + sizeof(buffer) - 1, v);
assert(r.ec == std::errc::result_out_of_range);
assert(!r); // Same as above but less verbose. Added in C++26.
In the event of std::errc::result_out_of_range, to_chars_result.ptr is equal to first
chars_format
chars_format overview
namespace boost { namespace charconv {
enum class chars_format : unsigned
{
scientific = 1 << 0,
fixed = 1 << 1,
hex = 1 << 2,
general = fixed | scientific
};
}} // Namespace boost::charconv
boost::charconv::chars_format
is used to specify the format of floating point types with from_chars
and to_chars
.
Scientific Format
Scientific format will be of the form 1.3e+03
.
The integer part will be between 0 and 9 inclusive. The fraction and exponent will always appear.
The exponent will always have a minimum of 2 digits.
Fixed Format
Fixed format will be of the form 2.30
or 3090
. An exponent will not appear with this format.
If the precision of to_chars
exceeds that of the type (e.g. std::numeric_limits<double>::chars10
), 0s will be appended to the end of the significant digits.
Hex Format
Hex format will be of the form 1.0cp+05
. The integer part will always be 0 or 1.
The exponent will be with a p instead of an e as used with base 10 formats, because e is a valid hex value.
Note: Every binary floating-point number has a unique representation as a hexfloat, but not every hexfloat has a unique representation as a binary floating-point number.
This is due to the fact that the number of bits in the significand of an IEEE754 binary32 and binary64 are not divisible by 4.
Hexfloat Use Cases
For those unfamiliar with hexfloats, they are valuable in specific instances:
-
Precision control: Hexfloats can offer finer control over the precision of floating-point values. In hexadecimal notation, each digit represents four bits (one hexit), allowing you to directly manipulate the precision of the number by specifying a certain number of hexadecimal digits. This can be useful when you need to precisely control the level of accuracy required for your calculations.
-
Bit-level representation: Hexfloats provide a direct representation of the underlying bits of a floating-point number. Each hexadecimal digit corresponds to a specific group of bits, making it easier to visualize and understand the internal structure of the floating-point value. This can be helpful for debugging or analyzing floating-point arithmetic operations (e.g. Computing ULP distances).
General
General format will be the shortest representation of a number in either fixed or general format (e.g. 1234
instead of 1.234e+03
.
Reference
<boost/charconv/from_chars.hpp>
Synopsis
namespace boost {
namespace charconv {
struct from_chars_result;
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 Real>
from_chars_result from_chars(const char* first, const char* last, Real& value, chars_format fmt = chars_format::general) noexcept;
// ...
} // namespace charconv
} // namespace boost
from_chars_result
struct from_chars_result
{
char const* ptr;
std::errc ec;
};
from_chars_result
is the return type of the from_chars
family of
overloaded functions.
The ec
member is std::errc()
when the conversion was successful, std::errc::invalid_argument
when no prefix of the passed characters form a valid value, or std::errc::result_out_of_range
when the characters form a value that would be out of range for the type.
The ptr
member points to the first character that is not part of the matched
value, or to last
if all characters matched.
from_chars
template <typename Integral>
BOOST_CXX14_CONSTEXPR from_chars_result from_chars(const char* first, const char* last, Integral& value, int base = 10) noexcept;
- Requires:
-
base
is between 2 and 36 inclusive. - Effects:
-
Attempts to interpret the characters in
[first, last)
as a numeric value in basebase
, consisting of an optional minus sign (only if the type is signed), and a sequence of digits. For bases above 10, the digit characters areAa
toZz
, as appropriate forbase
. - Returns:
-
The
ec
member of the return value isstd::errc()
on success,std::errc::invalid_argument
if[first, last)
can’t be interpreted as an integer of basebase
, orstd::errc::result_out_of_range
if[first, last)
when interpreted as an integer of basebase
can’t be represented as a value of typeIntegral
. Theptr
member of the return value points to the first character in[first, last)
that is not part of the matched value, or tolast
if all characters matched.
template <typename Real>
from_chars_result from_chars(const char* first, const char* last, Real& value, boost::charconv::chars_format fmt = boost::charconv::chars_format::general, int precision) noexcept;
- Requires:
-
fmt
has the value of one of the enumerators of chars_format. - Effects:
-
value is converted to a string in the style of printf in the "C" locale with the given precision. If a precision is not provided, the shortest representation will be given.
- Returns:
-
The
ec
member of the return value isstd::errc{}
on success,std::errc::invalid_argument
if the value can’t be interpreted with the given formatfmt
, orstd::errc::result_out_of_range
if the value can’t be represented in the target floating point type. Theptr
member of the return value points to the first character in[first, last)
that is not part of the matched value, or tolast
if all characters matched.
<boost/charconv/to_chars.hpp>
Synopsis
namespace boost {
namespace charconv {
struct to_chars_result;
template <typename Integral>
BOOST_CHARCONV_CONSTEXPR to_chars_result to_chars(char* first, char* last, Integral value, int base = 10) noexcept;
template <typename Real>
to_chars_result to_chars(char* first, char* last, Real value, chars_format fmt = chars_format::general, int precision) noexcept;
// ...
} // namespace charconv
} // namespace boost
to_chars_result
struct to_chars_result
{
char const* ptr;
std::errc ec;
};
to_chars_result
is the return type of the to_chars
family of
overloaded functions.
The ec
member is std::errc()
when the conversion was successful or std::errc::result_out_of_range
when the value cannot fit into the provided buffer.
The ptr
member points to the first character after the characters written,
or to last
when ec
is std::errc::result_out_of_range
.
to_chars
template <typename Integral>
BOOST_CHARCONV_CONSTEXPR to_chars_result to_chars( char* first, char* last, Integral value, int base = 10 ) noexcept;
- Requires:
-
base
is between 2 and 36 inclusive. - Effects:
-
The value of
value
is converted to a string of digits in the given base (with no redundant leading zeroes), which is stored in[first, last)
. Digits in the range 10..35 (inclusive) are represented as lowercase charactersa
..z
. If value is less than zero, the representation starts with a minus sign. - Returns:
-
The
ec
member of the return value isstd::errc()
on success orstd::errc::result_out_of_range
if[first, last)
does not contain enough space to hold the string representation ofvalue
. Theptr
member of the return value points to the character in[first, last]
that is one past the parsed characters, or tolast
whenec
isstd::errc::result_out_of_range
.
template <typename Real>
to_chars_result to_chars(char* first, char* last, Real value, chars_format fmt = chars_format::general, int precision) noexcept;
- Requires:
-
fmt has the value of one of the enumerators of chars_format.
- Effects:
-
The value is converted to a string in the style of printf in the "C" locale with the given precision. If no precision is provided the value character string will be the shortest representation of
value
. - Returns:
-
The
ec
member of the return value isstd::errc()
on success orstd::errc::result_out_of_range
if[first, last)
does not contain enough space to hold the string representation ofvalue
. Theptr
member of the return value points to the character in[first, last]
that is one past the parsed characters, or tolast
whenec
isstd::errc::result_out_of_range
.
<boost/charconv/limits.hpp>
Synopsis
namespace boost {
namespace charconv {
template<typename T> struct limits
{
static constexpr int max_chars10 = /*see below*/;
static constexpr int max_chars = /*see below*/;
};
} // namespace charconv
} // namespace boost
limits
template<typename T>
constexpr int limits<T>::max_chars10;
max_chars10
is the minimum size of the buffer that needs to be
passed to to_chars
to guarantee successful conversion for all values of
type T
, when either no base is passed, or base 10 is passed.
template<typename T>
constexpr int limits<T>::max_chars;
max_chars
is the minimum size of the buffer that needs to be
passed to to_chars
to guarantee successful conversion for all values of
type T
, for any base.
<boost/charconv.hpp>
This convenience header includes all headers previously mentioned.
Benchmarks
The values are relative to the performance of std::printf
and std::strtoX
.
Larger numbers are more performant (e.g. 2.00 means twice as fast, and 0.50 means it takes twice as long).
How to run the Benchmarks
To run the benchmarks yourself, navigate to the test folder and define BOOST_CHARCONV_RUN_BENCHMARKS
when running the tests.
An example on Linux with b2: ../../../b2 cxxstd=20 toolset=gcc-13 define=BOOST_CHARCONV_RUN_BENCHMARKS STL_benchmark linkflags="-lfmt" -a release
.
Additionally, you will need the following:
-
A compiler with full
<charconv>
support:-
GCC 11 or newer
-
MSVC 19.24 or newer
-
x86_64 Linux
Data in tables 1 - 4 were run on Ubuntu 23.04 with x86_64 architecture using GCC 13.1.0 with libstdc++.
Floating Point
Function | Relative Performance (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 |
Function | Relative Performance (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 |
Integral
Function | Relative Performance (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 |
Function | Relative Performance (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
Data in tables 5 - 8 were run on Windows 11 with x86_64 architecture using MSVC 14.3 (V17.7.0).
Floating Point
Function | Relative Performance (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 |
Function | Relative Performance (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 |
Integral
Function | Relative Performance (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 |
Function | Relative Performance (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
Data in tables 9-12 were run on MacOS Ventura 13.5.2 with M1 Pro architecture using Homebrew GCC 13.2.0 with libstdc++.
Floating Point
Function | Relative Performance (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 |
Function | Relative Performance (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 |
Integral
Function | Relative Performance (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 |
Function | Relative Performance (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 |
Special thanks to Stephan T. Lavavej for providing the basis for the benchmarks.
Sources
-
J.R. Parker A General Character to Integer Conversion Method, Software: Practice and Experience 15 (8), 1985.
-
Junkey Jeon, Faster integer formatting - James Anhalt (jeaiii)’s algorithm
-
William D. Clinger, How to Read Floating Point Numbers Accurately, 1990
-
Daniel Lemire, Number Parsing at a Gigabyte per Second, Software: Practice and Experience 51 (8), 2021.
-
Noble Mushtak, Daniel Lemire, Fast Number Parsing Without Fallback, Software: Practice and Experience (to appear)
-
Ulf Adams, Ryū revisited: printf floating point conversion, Proceedings of the ACM on Programming Languages Volume 3, 2019
Copyright and License
This documentation is copyright 2022-2023 Peter Dimov and Matt Borland and is distributed under the Boost Software License, Version 1.0.