Portable printing of exponent of a double to C++ iostreams

后端 未结 3 1583
鱼传尺愫
鱼传尺愫 2021-02-05 12:28

I want to print a double value to std::cout portably (GCC, clang, MSVC++) such that the output is the same on all platforms.

I have a problem with the forma

3条回答
  •  囚心锁ツ
    2021-02-05 13:24

    The problem is that Visual C++ was not following the C99 standard. In Visual C++ 2015, _set_output_format was removed since the compiler now follows the standard:

    The %e and %E format specifiers format a floating point number as a decimal mantissa and exponent. The %g and %G format specifiers also format numbers in this form in some cases. In previous versions, the CRT would always generate strings with three-digit exponents. For example, printf("%e\n", 1.0) would print 1.000000e+000. This was incorrect: C requires that if the exponent is representable using only one or two digits, then only two digits are to be printed.

    In Visual Studio 2005 a global conformance switch was added: _set_output_format. A program could call this function with the argument _TWO_DIGIT_EXPONENT, to enable conforming exponent printing. The default behavior has been changed to the standards-conforming exponent printing mode.

    See Breaking Changes in Visual C++ 2015. For older versions, see @Manuel's answer.

    FYI, in the C99 standard, we can read:

    e,E

    A double argument representing a floating-point number is converted in the style [-]d.ffffd e(+-)dd, where there is one digit (which is nonzero if the argument is nonzero) before the decimal-point character and the number of digits after it is equal to the precision; if the precision is missing, it is taken as 6; if the precision is zero and the # flag is not specified, no decimal-point character appears. The value is rounded to the appropriate number of digits. The E conversion specifier produces a number with E instead of e introducing the exponent. The exponent always contains at least two digits, and only as many more digits as necessary to represent the exponent. If the value is zero, the exponent is zero. A double argument representing an infinity or NaN is converted in the style of an f or F conversion specifier.

    This is a difference compared to C90 that did not give any indication concerning the required exponent length.

    Note that the recent Visual C++ changes also concern how to print nan, inf etc.

提交回复
热议问题