使用sprintf和%g将双精度转换为字符串的意外结果

时间:2018-08-28 14:34:37

标签: c++ printf

当我使用MBCS和msvcr120.dll(12.0.40660.0)时,将%g与sprintf一起使用将双精度型转换为字符串时,会得到意外的结果。 %g的文档说默认精度为6。为什么我看到下面的结果?

{
    double d = 1234567.00;
    char buf[100];

    sprintf_s(buf, sizeof(buf), "%g", d);

    //result is 1.23457e+006
}

为什么结果是1.23457e+006而不是1.23456e+006?截断会在6位数字后发生吗?

1 个答案:

答案 0 :(得分:5)

  

为什么我看到下面的结果?

这是C标准在[格式化的输入/输出功能]部分中指定格式的方式(C ++代表规范):

  

f,F

     

表示浮点数的 double 参数将转换为[-] ddd.ddd格式的十进制表示法,其中小数点字符后的位数等于精度规范。如果缺少精度,则取值为6;否则,取值为0。如果精度为零,并且未指定标志,则不显示小数点字符。如果出现小数点字符,则在其前面至少出现一位数字。该值将四舍五入为适当的位数。

     

e,E

     

表示浮点数的 double 参数将以[-] d.ddde±dd格式转换,其中在该参数之前有一个数字(如果参数为非零,则为非零)。小数点字符及其后的位数等于精度;如果精度丢失,则取为6;如果精度为零,并且未指定标志,则不显示小数点字符。该值将四舍五入为适当的位数。 E 转换说明符使用 E 而不是引入指数的 e 产生一个数字。指数始终至少包含两位数,并且仅包含表示指数所需的更多位数。如果值为零,则指数为零。

     

表示无穷大的 double 参数转换为以下一种样式: [-] inf [-] infinity -实现定义的。表示NaN的双引数会转换为 [-] nan *或** [-nan] (n-char-sequence)样式之一-哪种样式以及任何n-字符序列是实现定义的。 F转换说明符产生 INF INFINITY NAN 而不是 inf 无穷大 >或 nan

     

g,G

     

表示浮点数的 double 参数以 f e 风格(或以 F 风格)转换(如果是 G 转换说明符,则为strong>或 E ),具体取决于转换后的值和精度。假设P等于精度(如果非零),6(如果省略精度)或1(如果精度为零)。然后,如果样式为 E 的转换的指数为X

     
      
  • 如果P > X ≥ -4,则转换采用样式 f (或 F )和精度P - (X + 1)
  •   
  • 否则,转换的样式为 e (或 E ),精度为P - 1
  •   

  

为什么结果是1.23457e + 006而不是1.23456e + 006?

因为默认精度为6,并且该值四舍五入。

默认的舍入模式(根据IEEE 754)为“舍入到最接近值并保持偶数”。下一个和上一个回合值1.234567是1.23457和1.23456。 1.23457更近,因此1.234567会四舍五入至1.23457。