Chinaunix首页 | 论坛 | 博客
  • 博客访问: 832452
  • 博文数量: 330
  • 博客积分: 9641
  • 博客等级: 中将
  • 技术积分: 3181
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-19 14:41
文章分类

全部博文(330)

文章存档

2012年(17)

2011年(135)

2010年(85)

2009年(57)

2008年(36)

我的朋友

分类: LINUX

2010-03-19 11:04:27

C语言里面关于double类型的打印:%lf , %le , %lE
e/E是指数形式的,不过e打印的是小写,E打印的是大写。
g/G会截断一些小数,比较不精确。

%e     double   Signed   value   having   the   form   [   –   ]d.dddd   e   [sign]ddd   where   d   is   a   single   decimal   digit,   dddd   is   one   or   more   decimal   digits,   ddd   is   exactly   three   decimal   digits,   and   sign   is   +   or   –.   

%E   double   Identical   to   the   e   format   except   that   E   rather   than   e   introduces   the   exponent.   

%f   double   Signed   value   having   the   form   [   –   ]dddd.dddd,   where   dddd   is   one   or   more   decimal   digits.   The   number   of   digits   before   the   decimal   point   depends   on   the   magnitude   of   the   number,   and   the   number   of   digits   after   the   decimal   point   depends   on   the   requested   precision.   

%g   double   Signed   value   printed   in   f   or   e   format,   whichever   is   more   compact   for   the   given   value   and   precision.   The   e   format   is   used   only   when   the   exponent   of   the   value   is   less   than   –4   or   greater   than   or   equal   to   the   precision   argument.   Trailing   zeros   are   truncated,   and   the   decimal   point   appears   only   if   one   or   more   digits   follow   it.   

%G   double   Identical   to   the   g   format,   except   that   E,   rather   than   e,   introduces   the   exponent   (where   appropriate).  



一、实型常量
    实型也称为浮点型,实型常量也称为实数或浮点数。
    1.在纯C中,实型常量只能用十进制表示,但是有两种形式。
   (1)十进制小数形式:由数字0-9以及小数点构成,其中,小数点是必不可少的,如356.0、12.2等都是合法实数,65不是合法实数,因为缺少了小数点。
   (2)指数形式:由十进制数加阶码标志“E/e”组成,一般形式为a E n,其中a为十进制整数,E为阶码标志,n为十进制整数作为阶码,如123E5表示123*10^5,使用指数形式时,要注意E之前必须有数字,之后的阶码必须为整数。和数学中的科学计数法不同,一个实数可以有多种指数形式,如123.789可以表示为1.23789E2或12.3789E1或0.123789E3这些都是合法的,但是只有第一种才是规范化的指数形式,程序唉输出结果时都是以该种形式输出,但是其他形式在使用是也没有任何错误。
    2.在纯C中,也可以使用后缀“F/f”来声明一个数是浮点数,如365F和365.0是等价的。
    3.实例程序
    main()
    {
    printf("%f\n",365.0);
    printf("%f\n",365);
    printf("%f\n",365F);
    }
    运行结果是
    365.000000
    0.000000
    365.000000
    第二行输出错误的原因是,由于在使用时没有加入小数点,也没有使用后缀F将其声明为浮点数,所以365不是合法实数,不被编译器认可。
二、实型变量
    1.实型数据在内存中的存放形式:实型数据在内存中被分为符号部分,小数部分和指数部分三部分存放,例如-1.23456在内存中被分为“-”、“.123456”、“1”三个部分,一个实型数据占用4个字节的内存空间(1byte=8bits)通常,一般的C语言编译器会占用24位存放小数,8位存放指数,事实上,电脑在存取小数部分时,是以二进制形式的,而指数部分则是以2的幂指数形式存放的。
    2.实型数据的小数位数越多,代表有效数字越多,精度也就越高,而指数位数越多,器表示的数的范围就越大。
    3.实型变量的分类:实型变量可以分为三类,
   (1)单精度型:占用4字节内存空间,数值范围为3.4E-38到3.4E+38,有效数字为七位。
   (2)双精度型:占用8字节内存空间,数值范围为1.7E-308到1.7E+308,有效数字为十六位。
   (3)长双精度型:只是知道有这种数据类型,不过没有具体的数据,那位高人知道的话请补充一下。
    4.实型变量的定义格式和规则与整型数据相同,所以每一个实型数据在使用前必须先定义。
    实例:
    float m,n;        /*定义m,n为单精度实型变量*/
    double a,b,c;     /*定义a,b,c为双精度实型变量*/
    实例2:
    main()
    {
    float a;
    double b;
    a=5555.55555;
    b=5555.5555555555;
    printf("%f\n%f\n",a,b);
    }
    运行结果为5555.555664
      5555.555556
    分析:变量a被定义为float,变量b被定义为double,所以a的有效数字为七位,所以输出时5555.555之后的数字是无效的,而b的有效数字虽然为十六位,但是由于具体编译器的限制,只运算到小数点后六位,其余位数四舍五入。
    P.s编程技巧:对于实型数据,由于精度差别,大小差异极大的数值直接进行运算可能会丢失一部分数据。

三、puzzle from:   

float c = 12.5;
printf("%d\n", c);
printf("%d\n", *(int *)&c);

参考答案
该项程序输出如下所示,
0
1095237632
原因是:浮点数是4个字节,12.5f 转成二进制是:01000001010010000000000000000000,十六进制是:0×41480000,十进制是:1095237632。这是第二个输出的原因。对于第一个,为什么会输出0,我们需要了解一下float和double的内存布局,如下:

  • float: 1位符号位(s)、8位指数(e),23位尾数(m,共32位)
  • double: 1位符号位(s)、11位指数(e),52位尾数(m,共64位)

然后,我们还需要了解一下printf由于类型不匹配,所以,会把float直接转成double,注意,12.5的float和double的内存二进制完全不一样。别忘了在x86芯片下使用是的反字节序,高位字节和低位字位要反过来。所以:

  • float版:0×41480000 (在内存中是:00 00 48 41)
  • double版:0×4029000000000000 (在内存中是:00 00 00 00 00 00 29 40)

而我们的%d要求是一个4字节的int,对于double的内存布局,我们可以看到前四个字节是00,所以输出自然是0了。

这个示例向我们说明printf并不是类型安全的,这就是为什么C++要引如cout的原因了。

阅读(1484) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~