【问题标题】:Getting printf() to drop the trailing ".0" of values让 printf() 删除值的尾随“.0”
【发布时间】:2010-03-09 19:24:30
【问题描述】:

我需要打印具有以下格式要求的浮点数:

  • 5.12345 应该只显示5.1

  • 5.0 应该只有5(没有.0

  • 5.0176 应该只显示5(没有.01

我认为printf() 可以做这样的事情......但现在我似乎无法让它工作。

【问题讨论】:

  • 我认为我们需要对您想要的结果进行更系统的描述。现在,您已经给出了几个示例,但我完全不确定您想要(例如)15.2 的值是什么。您想要最多 2 位有效数字,还是只显示到单位位置,或者究竟是什么?
  • 5.06 的情况下你想要什么? Printf 可能会将其四舍五入到5.1。你想删除.1 吗?

标签: c printf


【解决方案1】:

您可以使用“%g”获得接近您想要的结果

#include <stdio.h>

int main(int argc, char* argv[])
{
        printf("%.6g\n", 5.12345f);
        printf("%.6g\n", 5.0f);
        printf("%.6g\n", 5.0176f);
        return 0;
}

输出:

5.12345
5
5.0176

"%g" 将删除尾随零。

【讨论】:

  • %.2g 将通过 OP 的所有三个测试。
  • @Max,我查看了手册页。如果他说%.2g,并打印100,他得到1.00e+02(如果指数大于或等于精度,%g 使用科学风格)。我认为这可能不是他想要的。
【解决方案2】:

听起来您想打印 1 个小数位,如果该位为 0,则将其删除。这个功能应该可以正常工作:

// prints the float into dst, returns the number
// of chars in the manner of snprintf. A truncated
// output due to size limit is not altered.
// A \0 is always appended. 
int printit(float f, char *dst, int max) {
  int c = snprintf(dst, max, "%.1f", f);

  if(c > max) {
    return c;
  }

  // position prior to '\0'
  c--;

  while(dst[c] == '0') {
    c--;
    if(dst[c] == '.') {
      c--;
      break;
    }
  }
  dst[c + 1] = '\0';  
  return c + 1;
}

int main(void) {
  char num1[10], num2[10], num3[10];
  printit(5.12345f, num1, 10);
  printit(5.0f, num2, 10);
  printit(5.0176f, num3, 10);
  printf("%s\n%s\n%s\n", num1, num2, num3);
}

【讨论】:

    【解决方案3】:

    printf() 可以使用格式化字符串。查看格式化字符串的宽度和精度选项:

    printf("%.1f", 5.12345f);
    

    这将打印5.1

    不幸的是,它没有能力在没有指导的情况下自动确定要显示的内容。 (例如,我不清楚您的最后一个选项 - 为什么要删除“.0176”,而不告诉它您不需要小数点?)

    【讨论】:

    • 这不会从 5.0 fyi 中删除 .0。
    • 但如果是 5.0,它将打印 5.0。在这种情况下,OP 想要打印 5。
    • @Dana:我不确定这是不是真的。看看 OP 的第一个选项——他们想要 5.1 换成 5.12345——那里不涉及 0...
    • 我想我会展示使用 printf 的可能性 - 如果这不是预期的结果,OP 可以澄清。
    • @Reed:它需要处理所有这些情况,而不仅仅是第一个。
    【解决方案4】:

    没有任何格式化操作符支持这一点,但是您可以先过滤floatsprintf(),然后在适当的地方截断字符串。这样就省去了将浮点数转换为字符串的麻烦,剩下的逻辑就很简单了。

    【讨论】:

    • 这样的一个问题是,如果需要的话,它不容易支持舍入。在原始帖子中,没有一个示例显示任何需要四舍五入的内容,因此我们不知道这是否是要求。
    【解决方案5】:

    不是你描述的那样,不。如果你想要条件小数位,你必须自己做。

    我已经有一段时间没有使用 printf 格式了,但这似乎在大多数情况下都有效

    char *BuildConditionalFormat(double val)
    {
        int tenths = (int)(val * 10) % 10;
        if (tenths == 0)
            return ".0f";
        return ".1f";
    }
    
    /* test rig */
    float f = 5.0;
    printf(BuildConditionalFormat(f), f); /* -> 5 */
    f = 5.13;
    printf("\n");
    printf(BuildConditionalFormat(f), f); /* -> 5.1 */
    printf("\n");
    

    这符合您的规则,但也将提供一个有趣的教训,即为什么浮点很臭,因为 5.1 -> 5。为什么?因为 5.1 并不能清楚地(在我的机器上)表示为浮点数 - 它是 5.09999 和更多变化。

    您可能还需要了解 floor() 和 ceil()...

    【讨论】:

      【解决方案6】:

      您可以告诉 printf 在 '.' 之后打印指定的位数,但是如果你想根据值来区分格式,你必须编写代码来区分你感兴趣的案例。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-07-23
        • 1970-01-01
        • 2020-03-31
        • 1970-01-01
        • 1970-01-01
        • 2012-11-03
        • 2017-09-19
        • 1970-01-01
        相关资源
        最近更新 更多