我正在尝试使用 printf 以仅打印前 n 个字符的方式打印浮点数 1.2345678、0.1234567、123.45678。我想让这些号码排成一行。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
我想让这些号码排成一行。printf("%*g", n, var) 中的 %g 格式说明符执行此操作
不,它不会 -%*g
您只是指定了最小字段宽度……在任何情况下,不存在或较小的字段宽度都不会导致字段截断;如果转换结果比字段宽度宽,则扩展字段以包含转换结果。[来自man 3 printf
]
但也许你%.*g
的意思是,指定精度……,有效数字的最大数量,它的行为根据你的问题描述。
以给定格式对齐数字的最佳方法是什么。通过使用 %g 或使用其他方法将 0 视为显着?
什么是最好的方法取决于数字的值范围。如果我们只有与您发布的相似的正数,我们可以简单地将前导零的精度降低一,例如:
printf("%.*g", n-(var<1), var);