sprintf%g说明符在点之后给出的位数太少

我正在尝试将浮点变量写入我的ini文件中,我遇到了格式说明符的问题。 我有一个浮动值,让它为101.9716。 现在我想将它写入我的ini文件,但问题是我有另一个浮点值,它具有较少的先决条件(例如15.85),并且该值正在同一循环中写入ini文件。 所以我这样做:

sprintf(valLineY, "%g", grade[i].yArr[j]); 

我所有的其他变量都变成了很好的字符,如“20”(如果它是20.00000),“13.85”(如果它是13.850000),依此类推。 但由于某种原因,101.9716变为“101.972”。 你能否告诉我为什么会发生这种情况以及如何在不破坏我的意识形态的情况下使其成为“101.9716”(这是关于删除尾随的零和不必要的感知)。 谢谢你的帮助。

为什么会这样?

我测试过:

 double f = 101.9716; printf("%f\n", f); printf("%e\n", f); printf("%g\n", f); 

它输出:

 101.971600 1.019716e+02 // Notice the exponent +02 101.972 

这是C标准(N1570 7.21.6.1)关于转换说明符g说法:

表示浮点数的double参数将以样式fe (或在G转换说明符的情况下以FE格式)转换,具体取决于转换的值和精度。 设P等于非零的精度,如果省略精度则设为6,如果精度为零则设为1。 然后,如果具有样式E的转换将具有指数X

– 如果P>X≥-4 ,则转换为样式f (或F )和精度P – (X + 1)

– 否则,转换采用样式e (或E )和精度P – 1

因此,如上所述, P将等于6,因为未指定精度,并且X将等于2,因为它是样式e上的指数。

因此,公式6> 2> = -4 ,并且选择了样式f 。 然后精度为6 – (2 + 1)= 3

怎么修?

f不同,样式g将删除不必要的零, 即使设置了精度也是如此

最后,除非使用#标志,否则从结果的小数部分删除任何尾随零,如果没有剩余小数部分,则删除小数点字符。

所以设置足够高的精度:

 printf("%.8g\n", f); 

打印:

 101.9716