Daniel Lemire's blog

, 1 min read

Rounding modes: std::from_chars versus strtod/strtof

A recent C++ standard (C++17) introduced new functions to parse floating-point numbers std::from_chars, from strings (e.g., ASCII text) to binary numbers. How should such a function parse values that cannot be represented exactly? The specification states that the resulting value rounded to nearest. This means that 1.0000000000000000001 and 0.999999999999999999 become exactly 1.0.

The C language has its own functions (strtod/strtof). I could not find a reference in the standard as to how it should round, but the source code suggests that the functions round according to the current floating-point rounding mode, as determined by the fegetround() function. One can round toward zero, up, down or to nearest. I wrote a small command-line utility to test it out. And indeed, I get the following results under LLVM and GCC:

string UPWARD DOWNWARD TONEAREST
1.0000000000000000001 1.00001 1.0 1.0
0.999999999999999999 1.0 0.999999 0.999999

Thus you cannot assume that, in general, std::from_chars will agree with strtod/strtof even for just boring strings such as 0.999999999999999999.

Thankfully, you can check the rounding mode efficiently.