c - float小數點兩位 - printf short




在printf%g格式說明符中將0作為有效數字處理 (2)

我試圖使用printf打印浮點數1.2345678,0.1234567,123.45678,這樣只打印前n個字符。 我想要這些號碼排隊。 printf(“%* g”,n,var)中的%g格式說明符是這樣做的,但說明符不是將0.1234567中的0作為有效數字。 這導致了0.1234567與另外兩個數字的對齊。

以給定格式對齊數字的最佳方法是什麼? 要么用%g來處理0,要么用其他方法處理?


根據定義,前導零不是有意義的數字。 如果要打印前N位數字(包括前導零),請首先將數字轉換為字符串,然後使用printf("%.*s", n, var_as_string)

這樣,前n字符確實打印,你問。 當然小數點. 與其他任何角色一樣,現在是重要的,與%g相反。


蠻力方法嘗試%.*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




specifier