将0视为printf%g格式说明符中的重要数字

时间:2016-12-30 18:13:49

标签: c format alignment printf specifier

我尝试使用printf打印浮点数1.2345678,0.1234567,123.45678,只打印前n个字符。我希望这些数字排成一行。 printf中的%g格式说明符("%* g",n,var)执行此操作,但说明符不将0.1234567中的0视为有效数字。这导致0.1234567的对齐与其他两个数字相对应。

在给定格式中对齐数字的最佳方法是什么。使用%g或使用其他方法将0视为显着?

3 个答案:

答案 0 :(得分:0)

By definition前导零不是重要数字。如果要打印前N个数字(包括前导零),请先将数字转换为字符串并使用printf("%.*s", n, var_as_string)

这样,就像你问的那样,确实会打印出第一个n个字符。当然,与.相反,任何其他字符的小数点%g现在都很重要。

答案 1 :(得分:0)

蛮力方法尝试%.*g的各种精确度,直到成功为止。

在调用printf()之前计算打印输出宽度的主要障碍是角落情况存在,如0.9995。舍入的微妙效果使得随后调用sprintf()更简单。可以使用其他代码来进行更好的初始猜测,而不是从prec = n - 1

开始
int g_print(double x, int n) {
  int width;
  char buffer[n + 1];
  for (int prec = n - 1; prec >= 0; prec--) {
    width = snprintf(buffer, sizeof buffer, "%.*g", prec, x);
    // printf("  n:%2d p:%2d w:%2d <%s>\n", n, prec, width, buffer);
    if (width > 0 && (unsigned) width < sizeof buffer) {
      return printf("%2d <%s>\n", n, buffer);
    }
  }
  // Try with %f
  width = snprintf(buffer, sizeof buffer, "%.0f", x);
  if (width > 0 && (unsigned) width < sizeof buffer) {
    return printf("%2d <%s>\n", n, buffer);
  }
  printf("%2d Fail %e\n", n, x);
  return 0; // fail
}

void g_print_test(double x) {
  // Need at least  width 7 for all values
  for (int n = 8; n >= 1; n--) {
    if (g_print(x, n) == 0)
      break;
  }
}


int main() {
  g_print_test(1.2345678);
  g_print_test(0.1234567);
  g_print_test(123.45678);
  g_print_test(DBL_MAX);
  g_print_test(-DBL_MAX);
  g_print_test(-DBL_MIN);
  return 0;
}

输出

 n  text...
 8 <1.234568>
 7 <1.23457>
 6 <1.2346>
 5 <1.235>
 4 <1.23>
 3 <1.2>
 2 <1>
 1 <1>
 8 <0.123457>
 7 <0.12346>
 6 <0.1235>
 5 <0.123>
 4 <0.12>
 3 <0.1>
 2 <0>
 1 <0>
 8 <123.4568>
 7 <123.457>
 6 <123.46>
 5 <123.5>
 4 <123>
 3 <123>
 2 Fail 1.234568e+02
 8 <1.8e+308>
 7 <2e+308>
 6 <2e+308>
 5 Fail 1.797693e+308
 8 <-2e+308>
 7 <-2e+308>
 6 Fail -1.797693e+308
 8 <-2e-308>
 7 <-2e-308>
 6 <-0>
 5 <-0>
 4 <-0>
 3 <-0>
 2 <-0>
 1 Fail -2.225074e-308

答案 2 :(得分:0)

  

我希望这些号码排队。 printf(“%* g”,n,var)中的%g格式说明符可以做到这一点

没有,这不 - 用%*g你只的指定最小字段宽度......在任何情况下做的一个不存在的或小的字段宽度截断        一个领域如果转换结果比字段宽度宽,         [来自man 3 printf]

但是也许您的意思是%.*g,指定 precision…,即最大        有效数字,该数字会根据您的问题描述进行操作。

  

什么是对准中给出的格式的数字的最好方式。是通过%g将0视为有效还是使用其他方法?

什么是最好的方式取决于数的取值范围。如果我们刚才类似的你张贴的正数,我们可以简单地通过一个前导零,E降低精度。 g。:

    printf("%.*g", n-(var<1), var);