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.

You may subscribe to this blog by email.