Implementation:Duckdb Duckdb Fast Float
| Knowledge Sources | |
|---|---|
| Domains | Parsing, Numeric_Processing, Third_Party |
| Last Updated | 2026-02-07 12:00 GMT |
Overview
fast_float is a high-performance C++ library for parsing floating-point numbers from character strings, providing IEEE-754 exact rounding.
Description
The duckdb_fast_float library is a vendored copy of the fast_float library by Daniel Lemire and Joao Paulo Magalhaes. It implements the from_chars function for converting character sequences to float or double values with exact IEEE-754 rounding ("round to even"). The implementation is locale-independent, does not throw exceptions, and performs zero heap allocations. DuckDB's copy lives under the duckdb_fast_float namespace to avoid symbol collisions with other libraries. It supports scientific notation, fixed-point notation, hexadecimal floating-point, and configurable decimal separators. The chars_format enum controls which notations are accepted, defaulting to general (both fixed and scientific).
Usage
DuckDB uses duckdb_fast_float::from_chars for high-throughput parsing of floating-point literals during CSV import, query constant evaluation, and CAST operations. It replaces slower standard library functions like std::strtod and std::from_chars with a significantly faster implementation that is critical for DuckDB's data ingestion performance.
Code Reference
Source Location
- Repository: Duckdb_Duckdb
- Files:
Signature
namespace duckdb_fast_float {
// Format flags controlling which notations are accepted
enum chars_format {
scientific = 1 << 0, // e.g., 1.23e4
fixed = 1 << 2, // e.g., 123.456
hex = 1 << 3, // e.g., 0x1.2p3
general = fixed | scientific // both fixed and scientific (default)
};
// Result struct returned by from_chars
struct from_chars_result {
const char *ptr; // pointer past the last parsed character
std::errc ec; // error code (std::errc() on success)
};
// Parse a floating-point number from the character range [first, last)
template<typename T>
from_chars_result from_chars(
const char *first,
const char *last,
T &value,
bool strict = false,
const char decimal_separator = '.',
chars_format fmt = chars_format::general
) noexcept;
} // namespace duckdb_fast_float
Import
#include "fast_float/fast_float.h"
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| first | const char* |
Yes | Pointer to the beginning of the character sequence to parse |
| last | const char* |
Yes | Pointer to one past the end of the character sequence |
| value | T& (float or double) |
Yes | Output reference where the parsed value is stored on success |
| strict | bool |
No | When true, requires the entire input range to be consumed; defaults to false
|
| decimal_separator | char |
No | The character used as the decimal point; defaults to '.'
|
| fmt | chars_format |
No | Bitmask controlling accepted notation (fixed, scientific, hex, general); defaults to general
|
Outputs
| Name | Type | Description |
|---|---|---|
| from_chars_result.ptr | const char* |
Points to the first character not consumed by the parse operation |
| from_chars_result.ec | std::errc |
std::errc() (zero) on success; std::errc::invalid_argument if no valid number found; std::errc::result_out_of_range if the value overflows the target type
|
| value | T (float or double) |
The nearest IEEE-754 floating-point representation of the parsed number, using round-to-even |
Usage Examples
#include "fast_float/fast_float.h"
#include <iostream>
// Basic float parsing
const char *input = "3.14159";
double value;
auto result = duckdb_fast_float::from_chars(input, input + 7, value);
if (result.ec == std::errc()) {
std::cout << "Parsed: " << value << std::endl; // 3.14159
}
// Parsing with custom decimal separator (e.g., European locale)
const char *euro_input = "1,23e4";
double euro_value;
auto euro_result = duckdb_fast_float::from_chars(
euro_input, euro_input + 6, euro_value,
false, ',' // use comma as decimal separator
);
// Scientific notation only
const char *sci_input = "6.022e23";
double sci_value;
auto sci_result = duckdb_fast_float::from_chars(
sci_input, sci_input + 8, sci_value,
false, '.', duckdb_fast_float::chars_format::scientific
);