我尝试使用printf打印浮点数1.2345678,0.1234567,123.45678,只打印前n个字符。我希望这些数字排成一行。 printf中的%g格式说明符("%* g",n,var)执行此操作,但说明符不将0.1234567中的0视为有效数字。这导致0.1234567的对齐与其他两个数字相对应。
在给定格式中对齐数字的最佳方法是什么。使用%g或使用其他方法将0视为显着?
答案 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);