C++浮点数转字符串的精度问题

来源:互联网 发布:苹果看图软件 编辑:程序博客网 时间:2024/06/16 06:09

C++中浮点数转字符串可调用 _gcvt_s 或 _ecvt_s 或 _fcvt_s

就 函数  _gcvt_s 而言

errno_t _gcvt_s(    char *buffer,   size_t sizeInBytes,   double value,   int digits );template <size_t cchStr>errno_t _gcvt_s(    char (&buffer)[cchStr],   double value,   int digits ); // C++ only

 参数 digits 表示格式化后的位数(包括小数点前后)

因为浮点数为不精确的表示方式, 所以必须要指定位数, 如

char txt[1024]; auto err = _gcvt_s(txt, 3.1415926, 1000);

txt 的值并不是 "3.1415926" 而是 "3.14159260000000006840537025709636509418487548828125" (Win7x64,VS2015, VC++ v140)

可参考 printf("%f", 3.1415926) 的默认实现, 将 digits 指定为 6(错误: %nf 是指将小数点后面保留n位, 不是整个浮点数的位数)

MSVC库源文件 X:\Program Files (x86)\Windows Kits\10\Source\10.0.10240.0\ucrt\inc\corecrt_internal_stdio_output.h line: 2324

            // The default precision depends on the format specifier used.  For
            // %e, %f, and %g, C specifies that the default precision is 6.  For
            // %a, C specifies that "if the precision is missing and FLT_RADIX
            // is a power of 2, then the precision is sufficient for an exact
            // representation of the value" (C11 7.21.6.1/8).
            //
            // The 64-bit double has 53 bits of precision.  When printing in
            // hexadecimal form, we print one bit of precision to the left of the
            // radix point and the remaining 52 bits of precision to the right.
            // Thus, the default precision is 13 (13 * 4 == 52).
            if (_format_char == 'a' || _format_char == 'A')
            {
                _precision = 13;
            }
            else
            {
                _precision = 6;
            }

0 0