使用sprintf和%g将double转换为string的意外结果

use*_*438 -1 c++ printf

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

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

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

    //result is 1.23457e+006
}
Run Code Online (Sandbox Code Playgroud)

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

eer*_*ika 5

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

这是C标准如何指定[格式化输入/输出函数]部分中的格式(C++委托规范):

F,F

表示浮点数参数被转换为十进制表示法中的风格[ - ] ddd.ddd,其中的小数点字符后的数字位数等于指定的精度.如果缺少精度,则取6; 如果精度是零,并且#未指定标志,则没有出现小数点字符.如果出现小数点字符,则在其前面至少出现一个数字.该值四舍五入到适当的位数.

选择e,E

表示浮点数参数被转换在样式[ - ] d.ddde±DD,其中在小数点字符和数字后的数量之前的一个位(这是非零如果参数为非零)它等于精度; 如果精度丢失,则取6; 如果精度是零,并且#未指定标志,则没有出现小数点字符.该值四舍五入到适当的位数.所述ë转换说明产生若干与Ë代替Ë引入指数.指数始终包含至少两个数字,并且只包含表示指数所需的更多数字.如果该值为零,则指数为零.

表示无限远参数被转换中的样式之一[ - ] INF[ - ]无穷大 -哪种风格实现定义的.表示NaN的双参数在样式[ - ] nan*或**[ - nan](n-char-sequence)之一中转换 - 哪种样式,以及任何n-char序列的含义,是实现 -定义.F转换说明符分别产生INF,INFINITYNAN而不是inf,infinitynan.

克,G

表示浮点数参数在风格转换˚FÈ(或风格˚FË中的情况下ģ转换说明),根据值转换和精度.让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.