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

标签 c++ c printf cvi

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

关于c++ - sprintf %g 说明符在点后给出的数字太少,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35475425/

相关文章:

c++ - 为什么我不能成为模板参数的 friend ?

c++ - 指向指针的指针,以便在 BattleShip 程序 c++ 中求和级别

c - 未定义的 Windows 引用 _ftprintf

golang十进制到十六进制转换错误

c++ - 影响和异常(exception)

c++ - 如何在 C++ 中修复 "invalid use of incomplete type"

c - 自动接触所有使用特定#define (#ifdef foo/#endif) 的文件

c - 在函数中访问内存 malloc 时出现段错误

c - 条件运算符中的 "error: lvalue required as left operand of assignment"

c - printf 格式字符串 lint 警告