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

sprintf %g specifier gives too few digits after point

我正在尝试将浮点变量写入我的 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:

A double argument representing a floating-point number is converted in style f or e (or in style F or E in the case of a G conversion specifier), depending on the value converted and the precision. Let P equal the precision if nonzero, 6 if the precision is omitted, or 1 if the precision is zero. Then, if a conversion with style E would have an exponent of X:

— if P > X ≥ −4, the conversion is with style f (or F) and precision P − (X + 1).

— otherwise, the conversion is with style e (or E) and precision P − 1.

所以上面给出的,P 将等于 6,因为没有指定精度,而 X 将等于 2,因为它是指数风格 e.

公式 6 > 2 >= -4 因此成立,样式 f 被选中。 精度将是 6 - (2 + 1) = 3.

如何修复?

f 不同,样式 g 会去除不必要的零,即使设置了精度

Finally, unless the # flag is used, any trailing zeros are removed from the fractional portion of the result and the decimal-point character is removed if there is no fractional portion remaining.

所以设置足够高的精度:

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

打印:

101.9716