实型变量的存储方式
实型变量共分三种:float、double、long double,这三种类型都是以浮点数的方式存储的,遵循IEEE标准。
浮点数的存储方式与编程的关系不大,通常我们编程用到浮点数时只关心变量中存的数值是多少,而不必知道它是怎么存的。这里我们简单介绍float型数据的存储方式以供需要的读者参考,double和long double型的存储与float型类似。
float型的任何数据存储前都要先表示为下面的格式:
(符号)* M*2n
其中:M是一个小数,n是指数。M必须在1.0~2.0之间1.0<=M<2.0,如果不在该范围内,则需调整。
如:30.0,表示为      + 1.875* 24
      -0.3925,表示为    -1.57*2-2
然后,计算机用4个字节,分成三部分分别存储符号、指数部分和小数部分。
上面三部分内容所占空间的大小如下表所示:
表7-2  浮点数存储空间的分配
符号位(01
指数部分(n+127)
小数部分 (M-1)
1  [31]
8 [30~23]
23 [22~00]
注:最右边是第0位,最左边是第31 
细心的读者肯定已经发现了,小数部分存储的是M-1而不是M,指数部分存储的是n+127而不是n,这样设计是有原因的。下面我们分别说明这三部分怎样存储。
(1)符号位:占一位,用0表示正,1表示负。
(2)指数部分:用一个字节存储,本来也有正负的,但是考虑到正负号的处理不方便,所以IEEE标准采用下面的方法:将指数部分加上一个偏移量127后再存储,例如:若实际指数为-2,则存储为125,若实际指数为4,则存储为131,即存储的是“实际指数加上127”。这样规定的目的,是可以不必设指数的符号位。指数位共8位,可表达的范围是0到255 ,而对应的实际指数是-127到+128 。
(3)小数部分:并不是存储浮点数的实际小数。按照规定,实际的小数1 .0<=M<2.0,这样,M的小数点前面将肯定有一个1,因此存储的时候,就可以不存1(将1默认了),而只存小数点后面的纯小数,即M-1。例如1.875,只存0.875 
综上所述,对于30.0=+ 1.875* 24:
符号位 :  0 (表示正)
指数部分:10000011  (其值131,表示指数是4)
小数部分: 11100000000000000000000(0.875,表示小数是1.875)
        其存储状态见图7-4。
0
1
0
0
0
0
0
1
1
1
1
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
7-浮点数30.0的存储状态
可以用下面的代码验证30.0存储状态:
#include <stdio.h>
int main()
{ union{
long m;
  float x;
}a;
a.x=30;
printf(“%lx\n”,a.m);
return 0;
}
其结果是:41f00000 即二进制的 0100 0001 1111 0000 0000 0000 0000 0000
二、实型变量常见使用问题
实数的存储有时候是不精确的。浮点型变量float
例如实数1.2,其纯小数部分化为二进制是一个无限循环小数: 00110011 00110011 00110011 00110011……,要想精确存储这个值,需要无限多的内存单元,而IEEE标准规定存储纯小数部分的空间只有23位,所以实际存储的数据只能是近似值。
实际上1.2的存储状态是 0 01111111 00110011001100110011010,这个状态表示的小数是1.2000000476837158203125,比1.2稍大。
由于实数存储的不精确,所以在程序中不要试图比较float型变量和float型常量是否相等。下面的程序输出结果是不相等。
#include <stdio.h>
int main()
{ float  x=0.2;
if(x==0.2)
  printf(“相等\n”);
else
  printf(“不相等\n”);
return 0;
}
出现这个结果的原因就是x中存储的不正好是0.2,而是近似值。你可能会用printf函数输出x,得到近似结果0.200000,但内存中存储的却不是这个值。
再看一个例子:
#include <stdio.h>
int main()
{ float  x;
  for(x=0.1; x!=1.0; x+=0.1)
    printf(“%4.1f”,x);
return 0;
}
这是一个无限循环,其输出结果是:0.1  0.2  0.3  0.4  0.5  0.6  0.7  0.8  0.9  1.0  1.1  1.2  1.3  ……
造成无限循环的原因是,x不断增加直到0.9(近似),然后再增加0.1,此时x1.0并不相同,因此循环不会停止。
避免这种错误发生的方法是,条件表达式中尽量不写==!=,而用<<=>>=代替。比如将上面循环的条件x!=1.0改写为 x<1.0

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。