Printf 里%f,%g的若干使用

引用一个很有用的网址:http://www.cplusplus.com/reference/cstdio/printf/  
%[flags][width][.precision][length]specifier   
先从几个test入手  
/************test 1**********/  
#include  
int main()  
{  
    printf("%10f\n",2.0);        //__2.000000       (2个空格)  
    printf("%10g\n",2.0);        //_________2   (9个空格)  
    printf("%10g\n",2.1);        //_______2.1   (7个空格)  
    printf("%f\n",2222222.10);   //2222222.100000  
    printf("%g\n",2222222.10);   //2.22222e+006  
    printf("%f\n",22.10);        //22.100000  
  printf("%g\n",22.10);       //22.1  
  printf("%.4g\n",234.5);   //234.5  
  printf("%.4f\n",234.5);    //234.5000   
}  
于是,%g 可以理解为科学技术法输出,没有.xf情况下默认保留六位有效数字(否则保留x位),自动省略后导0再输出  
/************test 2***********/  
#include  
int main()  
{   printf("%.f\n",2.5);        //3  
    printf("%.0f\n",2.5);       //3  
  printf("%.3f\n",2.5);         //2.500  
  printf("%#.0f\n",2.5);        //3.  
于是,#为强制输出小数点  
}/************test 3***********/  
Cpp1  
#include  
int main()  
{   printf("%f\n",5);            //0.000000  
    printf("%f\n",123.0);        //123.000000  
}  
Cpp2  
#include  
int main()  
{   printf("%f\n",123.0);       //123.000000  
    printf("%f\n",5);           //123.000000  
}  
如何理解?  
引用http://blog.csdn.net/liaozhen/article/details/1778165  
首先123.0默认转化为64位double,5转化为32位int    //这行可能有错,但不用太在意  
然后Cpp1先输出5相当于前32位为初始化(全0),根据64位小数1+10+53,符号位为0,指数位十位也全为0,1.101再将小数点左移127位,所以是0.000000,事实上不是0,是个比较小的小数而已。  
而Cpp2先输出123后并没有清空,导致前32位残留,于是影响了5正常输出,至于为什么是123.000000,可类比cpp1推导。  
PS:如果把5改成5.0自然不会有这些事情  
  
  
  
下面应用到具体的题目上  
POJ 1004  
累加12个小数点后有两位的小数到sum,  
再将一个double型sum四舍五入至两位小数输出  
一、利用%g  
    int d=sum/10000;  
    sum-=d*10000;  
    if(!d) printf("%g\n",sum);  
    else printf("%d%g\n",d,sum);  
二、转换成字符串后再输出  
    sprintf(b, "%.2lf", sum);     
    int len = strlen(b);  
    if (b[len-1] == '0')  
      {  
            b[len-1] = 0;//*1  
            len --;  
            if (b[len-1] == '0')  
            {  
                b[len-1] = 0;//*2  
                len --;  
                if (b[len-1] == '.')  
                {  
                    b[len-1] = 0;//*3  
                    len --;  
                }  
            }  
      }  
    printf("%s\n", b);  
    //注意*1*2*3均不可省略,相当于重新修改字符串的长度。  
    //当然如果最后用for语句和len输出是可以删除这三句话的。  
三、较常规的做法,不过有坑  
    tmp=int(sum*100+0.5);  
    if (tmp%100==0) printf("%d\n",tmp/100);  
    else if (tmp%10==0) printf("%d.%d\n",tmp/100,tmp/10%10);  
  else printf("%d.%02d\n",tmp/100,tmp%100);  
  坑:比如小数1.03  
  最后的%02d坑死了  
  %2d 会输出1.空格3  
  %d 会输出1.3  
  这两者都不行,要02d!!!  
    跟钟表有关的也是t%60 一定要%02d输出  
 四、字符串读入,将读入的小数统一扩大10^X倍(不推荐),整数处理  
    此题这个sum是整数是12个题干中小数点后两位的小数忽略小数点产生的新的整数的和  
    is=sum/12;  
    if(sum%12>=6)is++;  
    printf("%d",is/100);  
    is%=100;  
    if(is)  
     {  printf(".");  
        if(is%10==0)printf("%d",is/10);  
        else if(is<10)printf("0%d",is);  //还不如   方法三,除非能记得这句  
        else printf("%d",is);  
     }  
 最后,感谢LJW和HYK提供的无限帮助~~~  


 
 

你可能感兴趣的:(【STL&&IO】)