In C++20 you'll be able to use [`std::format`](https://en.cppreference.com/w/cpp/utility/format) to do this:
```c++
std::stringstream ss;
double v = 0.1 * 0.1;
ss << std::format("{}", v);
double u;
ss >> u;
assert(v == u);
```
The default floating-point format is the shortest decimal representation with a round-trip guarantee. The advantage of this method compared to using the precision of `max_digits10` from `std::numeric_limits` is that it doesn't print unnecessary digits.
In the meantime you can use [the {fmt} library](https://github.com/fmtlib/fmt), `std::format` is based on.
**Disclaimer**: I'm the author of {fmt} and C++20 `std::format`.
In C++20 you'll be able to use [`std::format`](https://en.cppreference.com/w/cpp/utility/format) to do this:
```
std::cout << std::format("{}", M_PI);
```
Output (assuming IEEE754 `double`):
```none
3.141592653589793
```
The default floating-point format is the shortest decimal representation with a round-trip guarantee. The advantage of this method compared to the `setprecision` I/O manipulator is that it doesn't print unnecessary digits.
In the meantime you can use [the {fmt} library](https://github.com/fmtlib/fmt), `std::format` is based on. {fmt} also provides the `print` function that makes this even easier and more efficient ([godbolt](https://godbolt.org/z/ej48Wa)):
```
fmt::print("{}", M_PI);
```
**Disclaimer**: I'm the author of {fmt} and C++20 `std::format`.