2

我正在尝试使用 printf 以仅打印前 n 个字符的方式打印浮点数 1.2345678、0.1234567、123.45678。我想让这些号码排成一行。printf("%*g", n, var) 中的 %g 格式说明符会执行此操作,但说明符不会将 0.1234567 中的 0 视为有效数字。这会导致 0.1234567 的对齐方式偏离其他两个数字。

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

4

3 回答 3

0

根据定义,前导零不是有效数字。如果要打印前 N 位数字,包括前导零,请先将数字转换为字符串并使用printf("%.*s", n, var_as_string).

这样n,如您所问,确实打印了第一个字符。当然.,与任何其他字符一样,小数点现在很重要,与%g.

于 2016-12-30T18:55:52.237 回答
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
于 2016-12-30T21:13:40.463 回答
0

我想让这些号码排成一行。printf("%*g", n, var) 中的 %g 格式说明符执行此操作

不,它不会 -%*g您只是指定了最小字段宽度……在任何情况下,不存在或较小的字段宽度都不会导致字段截断;如果转换结果比字段宽度宽,则扩展字段以包含转换结果。[来自man 3 printf]

但也许你%.*g的意思是,指定精度……,有效数字的最大数量,它的行为根据你的问题描述。

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

什么是最好的方法取决于数字的值范围。如果我们只有与您发布的相似的正数,我们可以简单地将前导零的精度降低一,例如:

    printf("%.*g", n-(var<1), var);
于 2019-02-01T13:15:01.773 回答