【问题标题】:Number of digits printed in C program [duplicate]C程序中打印的位数[重复]
【发布时间】:2021-10-18 05:35:27
【问题描述】:

如何可变地影响 C 程序中打印的位数?我不想在十进制开发中写入不必要的零

x=7 输出:7

x=7.700 输出 7.7

x=7.77700 输出:7.777

我的意思是不要固定 printf ("%.3lf", yourVariable); ,但它在我要发送到那里的值上发生了变化

【问题讨论】:

  • 在科学背景下,7.7 与 7.700 不同。我们怎么知道哪些小数是“不必要的”?
  • 这里我有正常的十进制数字,示例中的所有零都是不必要的
  • 你想从十进制数中删除所有不必要的 0 吗?就像你写 5.34000000 并且输出应该是 5.34?
  • @Karnal-YK 是的。
  • @Aaron7 你可以简单地使用类型转换。取任意数字并将其转换为浮点数。正如我在回答中显示的那样

标签: c


【解决方案1】:

您可以在 C 中使用 %g Format Specifier 来实现此目的。

Working Fiddle

工作代码

#include <stdio.h>
int main() {   
    float number;
   
    printf("Enter an integer: ");  
    
    // reads and stores input
    scanf("%f", &number);

    // displays output
    printf("You entered: %g", number);
    
    return 0;
}

【讨论】:

  • 可能想评论一下,如果值为double,那么scanf() 将需要%lf。对g转换说明符有深刻理解,值得UV。
【解决方案2】:

我相信您正在寻找的是一种无需硬编码即可动态更改输出精度的方法。

如果您可以访问 c99 编译器,则可以使用 snprintf 生成格式字符串,例如:

char* format_width(double x, unsigned prec) {
  int fmt_size = snprintf (NULL, 0, "%%.%ulf", prec);
  char* fmt_string = malloc(fmt_size + 1);
  snprintf(fmt_string, fmt_size + 1, "%%.%ulf", prec);
  
  int out_size = snprintf (NULL, 0, fmt_string, x);
  char* out_string = malloc(out_size + 1);
  snprintf(out_string, out_size + 1, fmt_string, x);
  
  free(fmt_string);
  return out_string;
}

用法可能类似于

int main() {   
    double number;
    unsigned prec;
   
    printf("Enter a number: ");  
    
    // reads and stores input
    scanf("%lf", &number);
    
    printf("Enter precision: ");  
    
    // reads and stores precision
    scanf("%u", &prec);
    
    char* result = format_width(number, prec);
    // displays output
    printf("You entered: %s", result);
    
    free(result);
    
    return 0;
}

Demo


优化分配

为了避免过多的分配,可以使用一个合理大小的缓冲区来生成格式说明符。例如,fmt_string 不太可能超过 15 个字符,因此我们可以优化该部分。

也有可能用户已经知道他们可能收到的输入的最大大小,所以我们可以允许他们传入out_string缓冲区(假设它足够大以包含结果)

char* format_width(double x, unsigned prec, char* out_string) {
  static char fmt_string[15];
  snprintf(fmt_string, 15, "%%.%ulf", prec);

  int out_size = snprintf (NULL, 0, fmt_string, x);
  snprintf(out_string, out_size + 1, fmt_string, x);
  
  return out_string;
}

【讨论】:

  • Worthy of UV for snprintf (NULL, 0 ... 用于调整所需字符数的技巧。但是考虑传递一个自动存储持续时间(合理足够大小)的数组作为第三个参数,以避免分配存储并消除在循环调用函数的情况下释放存储的负担。如果用户正在扫描大量浮点值,可能会成为热点。
【解决方案3】:

您可以简单地将其转换为浮点数

x = (float)x;

IT 将删除所有不必要的 0。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-28
    • 2015-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多