在printf%g格式说明符中将0作为有效数字处理 [英] Treating 0 as a significant figure in printf %g format specifier

查看:240
本文介绍了在printf%g格式说明符中将0作为有效数字处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用printf打印浮点数1.2345678,0.1234567,123.45678,只打印前n个字符。我想要这些号码排队。 printf(%* g,n,var)中的%g格式说明符是这样做的,但说明符不是将0.1234567中的0作为有效数字。这导致了0.1234567与其他两个数字的对齐。



对齐给定格式的数字的最佳方法是什么?或者通过用%g或者使用其他方法将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,prec,width,buffer);
if(width> 0&(unsigned)width< sizeof buffer){
return printf(%2d<%s> \\\
,n,buffer);


//尝试使用%f
width = snprintf(buffer,sizeof buffer,%.0f,x);
if(width> 0&(unsigned)width< sizeof buffer){
return printf(%2d<%s> \\\
,n,buffer);
}
printf(%2d失败%e \ n,n,x);
返回0; //失败
}

void g_print_test(double x){
//至少需要宽度为7的所有值
for(int n = 8; n> ; = 1; n--){
if(g_print(x,n)== 0)
break;



$ b 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);
返回0;






$ b $ pre> n文字...
8< 1.234568>
7< 1.23457>
6< 1.2346>
5 <1.235>
4 <1.23>
3 1.2< 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< 123>
3 123>
2失败1.234568e + 02
8< 1.8e + 308>
7< 2e + 308>
6< 2e + 308>
5不合格1.797693e + 308
8< -2e + 308>
7< -2e + 308>
6失败-1.797693e + 308
8< -2e-308>
7< -2e-308>
6< -0>
5< -0>
4< -0>
3< -0>
2< -0>
1失败-2.225074e-308


I'm trying to print floating point numbers 1.2345678, 0.1234567, 123.45678 using printf in such a way that only the first n characters are printed. I want these number to line up. The %g format specifier in printf("%*g", n, var) does this but the specifier is not treating the 0 in 0.1234567 as a significant figure. This causes the alignment of 0.1234567 to go off wrt to the other two figures.

What's the best way to align the numbers in the formats given. Either by treating 0 as significant with %g or using some other method?

解决方案

A brute force method tries various precisions of %.*g until success.

The major obstacle to calculating the width of the print out before calling printf() is that corner cases exist like 0.9995. The subtle effects of rounding make it that it is simpler to call sprintf() a subsequent time. Additional code could be uses to make a better initial guess rather than starting at 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;
}

Output

 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格式说明符中将0作为有效数字处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆