C/C++浮点数简述一:模型

c/c++采用IEEE表示法存储浮点类型,公式为:
(-1)s x M x 2 E
其中:
s是符号位,决定正数(0)还是负数(-1),数值为0的数字符号位做特殊处理。
M是二进制有效数。
E是2的幂,作用是对2进制加权。
那么在C中,存储格式如下:
s
f(M=1+f orM=f)
e(E=e-bias bias  2k-1  k E 的位数)
0(1) | 1-23(23 )    | 24-31(8 )    | 32
0(1) | 1-52(52 )    | 53-63(11 )  |64 
 
 
而根据 E的值的不同浮点数的表示方法有一下三种:
规范化值:
E为无符号数,当E不是全 0或者全1 时,此时就是用于规范化表示。
E = e-biase k位, kE 的位数, bias2 k-1 ,由此确定,E的取值范围
对于单精度来说是 -126 - +127,双精度为-1022 - + 1023 
M=f+10<=f<1 ,即二进制值为 0.fn-1 fn-2…f 1f0 ,需要注意的是 隐含的1 ,因为我们总是能够调节指数,使 1<=M<2,那么小数第一位肯定是 1,而这个1 我们就不用显示的表示它了,这样可以获得额外一位。     
非规范化值:
 当指数E 二进制位全 0时,所表现的数就是非规范化形式的,这种情况下指数值为 E=1-bias
M=f,此时 1不被隐含。因为规格化时有一个隐含的 1,所以不能表示0,而规范化值可以表示 0。+0和负0在IEEE标准中是是不一样的,但是C库是不区分的,但有个例外:1/负0结果是负无穷,而1/正0结果是正无穷。正0和负0比较是一样的。我觉得C库应该是在0参与的运算当中是区分正负的,但是直接比较0时,是不区分的。这里使用1-bias 是为了从非规范化值向规范化值的平滑转换,非规范化值的最大表示恰巧是规范化值的最小表示,此时转换,我们只需要将 e转为1 ,再加上一个隐含 1就可以完成。
特殊值:
当指数值 E为全1 M全为 0时,表示的值是无穷,当 s0 时,表示的是正无穷,当 s1 时,表示的是负无穷,当小数值不为 0时,结果为NaN ,即不是一个数,如求 -1的开根。
具体的IEEE标准可以参看wiki http://zh.wikipedia.org/wiki/IEEE_754
posted @ 2013-10-31 11:38  屠戮者  阅读(783)  评论(0)    收藏  举报