【问题标题】:At least one decimal after dot with printf in CC中的printf点后至少一位小数
【发布时间】:2019-08-31 15:06:03
【问题描述】:

我正在寻找一种在 C 中打印浮点数的方法,该方法在点后至少打印一个小数,但仍会截断尾随零,例如

double x = 5.0;
printf("<some_format>", x);
// should print 5.0, not 5, and not 5.000000

double y = 5.10;
printf("<same_format>", y);
// should print 5.1, not 5.10, and not 5.100000

double x = 5.1230;
printf("<same_format>", z);
// should print 5.123, not 5.1230

另外,定义最大或固定数量的数字/小数正是我想要避免的。

有人知道使用printf 完成此操作的一种格式,而无需将数字写入字符缓冲区然后手动编辑此缓冲区?

【问题讨论】:

  • 你试过什么?您的尝试是如何奏效的?
  • 带有 %g 和 %f 的标准内容,并阅读了 printf 的手册页,我没有看到任何关于此问题的信息。
  • 这真的很难,如果不是不可能的话,因为真的没有办法知道一个浮点值到底有多少个小数。

标签: c string printing terminal printf


【解决方案1】:

如果我正确理解您的问题,您希望5.0 打印为5.05.10 打印为5.15.15 打印为5.15...

没有简单的方法可以用printf 实现此目的,因为问题并不那么简单:5.10 在 C 中表示为 double,其二进制编码的小数部分是 5.1 的近似值,不是一个精确的表示。如果你用足够多的小数打印它,你会看到它停止产生尾随零:

    printf("%.23f", 5.10) -> 5.09999999999999999991326

所以你的问题应该是:

如何打印包含至少n 但最多p 小数的浮点数,省略尾随零?

这可以通过将p 作为sprintf%f 的精度字段传递并运行一个循环来删除n 之外的尾随零和如果n0 的尾随句点来实现。

这是一个例子:

#include <stdio.h>

int print_double(double value, int n, int p) {
    char buf[400];
    int dot;
    int len;
    len = snprintf(buf, sizeof buf, "%.*f", p, value);
    if (len >= (int)sizeof(buf)) {
        printf("value too large: %g\n", value);
        return -1;
    }
    for (dot = 0; dot < len;) {
        if (buf[dot++] == '.')
            break;
    }
    while (len - dot > n && buf[len - 1] == '0')
        len--;
    if (len > 0 && buf[len - 1] == '.')
        len--;
    buf[len] = '\0';
    printf("%s\n", buf);
    return len;
}

int main(int argc, char *argv[]) {
    print_double(5.0, 1, 2);
    print_double(5.1, 1, 2);
    print_double(5.15, 1, 2);
    return 0;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    • 1970-01-01
    • 2015-01-04
    • 1970-01-01
    • 1970-01-01
    • 2013-05-01
    相关资源
    最近更新 更多