【问题标题】:Why does printf("%.6g, <value>) ignore zeroes after decimal point?为什么 printf("%.6g, <value>) 忽略小数点后的零?
【发布时间】:2012-05-20 07:30:04
【问题描述】:

我想在小数点后最多打印 6 位,所以我使用了以下内容:

printf("%.6g",0.127943989);

printf 的输出是 0.127944,这是正确的,但是当我尝试这样做时:

printf("%.6g",0.007943989);

输出变成了 0.00794399,这不是我期望看到的!

printf 似乎忽略了小数点后的零。那么如何强制它输出最大 6 位精度呢?

【问题讨论】:

  • 尝试添加 # 不确定是否有效。
  • 看来小数位数真的是非前导零小数位数。
  • 您使用的是哪个 C 库? glibc 好像没有这个问题。

标签: c floating-point double printf precision


【解决方案1】:

"%f" 格式说明符:

printf("%.6f\n",0.007943989)  // prints 0.007944

您在寻找什么?请记住,如果数量允许,这不会自动切换到 %e 格式样式,因此这可能也不是您要寻找的。​​p>

例如:

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

打印:

7.94399e-005
0.000079

不清楚您是否想要"%g" 提供的较小数字的指数形式。

请注意,%f%g 的规范对于精度规范的处理方式略有不同。

  • for%f:“小数点字符后的位数等于精度规范”
  • 对于%g:“具有指定有效位数的精度”

并且小数点后的零不计入有效数字(这解释了您在%g 中看到的行为)。

【讨论】:

  • %f 将打印 EXACTLY 小数点后 6 位数字。我想要最多 6 位数字。例如,如果数字是“0.12”,我希望得到 0.12,但如果是“0.0012345678”,我希望得到 0.001234,并且指数形式没有问题。
  • 嗯...谢谢,但我怎样才能产生预期的结果?我不能使用 %f 因为我不想要固定的 6 位精度。由于您给出的解释,我不能使用 %g 。我该怎么办?
  • 嗯,可能有更好的方法,但由于我在浮点数方面不太聪明,我可能会使用 %fsnprintf() 格式化东西,然后剥离关闭尾随零。或类似的东西。但就像我说的,有人可能知道更好的方法......
  • @MichaelBurr 遗憾的是,您的方式是解决此问题的唯一方法。我也在等待更好的方法:(
【解决方案2】:

ISO C 标准要求

可选精度,以句点 ('.') 的形式,后跟 一个可选的十进制数字字符串...这给出了...最大值 gG 转换的有效位数

这是使用 GNU libc(GCC 4.5.1、libc 2.11;GCC 4.6.3、libc 2.15)获得的输出

printf("%.6g\n", 0.12);
0.12
printf("%.6g\n", 0.1234567890);
0.123457
printf("%.6g\n", 0.001234567890);
0.00123457
printf("%#.6g\n", 0.001234567890);
0.00123457
printf("%.6g\n", 0.00001234567890);
1.23457e-05
printf("%#.6g\n", 0.00001234567890);
1.23457e-05

printf("%.6f\n", 0.12);
0.120000
printf("%.6f\n", 0.1234567890);
0.123457
printf("%.6f\n", 0.001234567890);
0.001235
printf("%#.6f\n", 0.001234567890);
0.001235
printf("%.6f\n", 0.001234567890);
0.000012
printf("%#.6f\n", 0.001234567890);
0.000012

【讨论】:

  • 是的。你知道的就是微软! ;P 叹息
  • 我错过了什么吗?我在 Linux 3.0 上看到的 MSVC 输出和 GCC 4.6.1 之间的唯一区别(我不知道使用了哪个 libc)是 MSVC 使用 3 位指数而不是 2 位指数(即 MSVC 打印 1.23457e-005 而 libc打印1.23457e-05)。
  • @michael-burr 显然 OP 在 VC++2010 中得到 0.00794399 而不是 7.94399e-005。我也无法确认。
  • @Dmitri:当将数字0.007943989 传递给printf() 并使用"%g" 说明符时,OP 正在获取0.00794399。这就是应该打印的内容(也是 libc 打印的内容)。如果 0.00007943989 被传递,则 MSVC 打印 7.94399e-005 与 libc 的 7.94399e-05 相比。 MSVC 遵循 C90 标准,它只说指数至少有两位数(C99 标准说它至少有两位数,但仅在必要时更多)。
  • 这个答案引用了错误的来源,但在其他方面是正确的。指定 %g 行为的是 ANSI/ISO C。
猜你喜欢
  • 1970-01-01
  • 2013-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多