[/
  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<T>::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<T>::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<T>(ss.str()); // Get read by converting from decimal digits string representation of write.
  BOOST_CHECK_EQUAL(read, write);

  read = static_cast<T>(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

   <number<cpp_bin_float<53, digit_count_2> >

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]
