[/ Copyright 2011 - 2020 John Maddock. Copyright 2013 - 2019 Paul A. Bristow. Copyright 2013 Christopher Kormanyos. Distributed under the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt). ] [section:input_output Input Output] [h4 Loopback testing] ['Loopback] or ['round-tripping] refers to writing out a value as a decimal digit string using `std::iostream`, usually to a `std::stringstream`, and then reading the string back in to another value, and confirming that the two values are identical. A trivial example using `float` is: float write; // Value to round-trip. std::stringstream ss; // Read and write std::stringstream. ss.precision(std::numeric_limits::max_digits10); // Ensure all potentially significant bits are output. ss.flags(std::ios_base::fmtflags(std::ios_base::scientific)); // Use scientific format. ss << write; // Output to string. float read; // Expected. ss >> read; // Read decimal digits string from stringstream. BOOST_CHECK_EQUAL(write, read); // Should be the same. and this can be run in a loop for all possible values of a 32-bit float. For other floating-point types `T`, including __fundamental `double`, it takes far too long to test all values, so a reasonable test strategy is to use a large number of random values. T write; std::stringstream ss; ss.precision(std::numeric_limits::max_digits10); // Ensure all potentially significant bits are output. ss.flags(f); // Changed from default iostream format flags if desired. ss << write; // Output to stringstream. T read; ss >> read; // Get read using operator>> from stringstream. BOOST_CHECK_EQUAL(read, write); read = static_cast(ss.str()); // Get read by converting from decimal digits string representation of write. BOOST_CHECK_EQUAL(read, write); read = static_cast(write.str(0, f)); // Get read using format specified when written. BOOST_CHECK_EQUAL(read, write); The test at [@../../test/test_cpp_bin_float_io.cpp test_cpp_bin_float_io.cpp] allows any floating-point type to be ['round_tripped] using a wide range of fairly random values. It also includes tests compared a collection of [@../../test/string_data.ipp stringdata] test cases in a file. [h4 Comparing with output using __fundamental types] One can make some comparisons with the output of > which has the same number of significant bits (53) as 64-bit double precision floating-point. However, although most outputs are identical, there are differences on some platforms caused by the implementation-dependent behaviours allowed by the C99 specification [@http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf C99 ISO/IEC 9899:TC2], incorporated by C++. [:['"For e, E, f, F, g, and G conversions, if the number of significant decimal digits is at most DECIMAL_DIG, then the result should be correctly rounded. If the number of significant decimal digits is more than DECIMAL_DIG but the source value is exactly representable with DECIMAL_DIG digits, then the result should be an exact representation with trailing zeros. Otherwise, the source value is bounded by two adjacent decimal strings L < U, both having DECIMAL_DIG significant digits; the value of the resultant decimal string D should satisfy L<= D <= U, with the extra stipulation that the error should have a correct sign for the current rounding direction."]] So not only is correct rounding for the full number of digits not required, but even if the *optional* recommended practice is followed, then the value of these last few digits is unspecified as long as the value is within certain bounds. [note Do not expect the output from different platforms to be [*identical], but `cpp_dec_float`, `cpp_bin_float` (and other backends) outputs should be correctly rounded to the number of digits requested by the set precision and format.] [h4 Macro BOOST_MP_MIN_EXPONENT_DIGITS] [@http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf C99 Standard] for [/e and E] format specifiers, 7.19.6 Formatted input/output functions requires: \"The exponent always contains at least two digits, and only as many more digits as necessary to represent the exponent.\" So to conform to the C99 standard (incorporated by C++) #define BOOST_MP_MIN_EXPONENT_DIGITS 2 Confusingly, Microsoft (and MinGW) do not conform to this standard and provide [*at least three digits], for example `1e+001`. So if you want the output to match that from __fundamental floating-point types on compilers that use Microsofts runtime then use: #define BOOST_MP_MIN_EXPONENT_DIGITS 3 Also useful to get the minimum exponent field width is #define BOOST_MP_MIN_EXPONENT_DIGITS 1 producing a compact output like `2e+4`, useful when conserving space is important. Larger values are also supported, for example, value 4 for `2e+0004` which may be useful to ensure that columns line up. [endsect] [/section:input_output Input Output]