Menu Close

浮点数的存储和浮点数有效数字及浮点数范围

浮点数在计算机中的表示和存储方式

根据IEEE标准,浮点数是通过科学计数法来存储的,比如120.5用十进制的科学计数法来表示就是1.205*102.但是计算机中所有数据都是用二进制存储的,所以得先转换为二进制数,即1.1110001*26.

%title插图%num

浮点数在计算机中的存储分为三个部分:
1. 符号位(sign):float和double符号位均为1位,0代表正数,1代表负数
2. 指数位(exponent):存储科学计数法中的指数部分,采用移位存储
3. 尾数位(Mantissa, fraction):存储科学计数法中的尾数部分

 

%title插图%num

根据IEEE 754标准,单精度float类型使用32比特(4节)存储,其中1位表示符号,8位表示指数,23位表示尾数;双精度double类型使用64比特(8节)存储,1位符号位,11位指数位,52位尾数位。

float存储示例

以数字6.5为例,看一下这个数字是怎么存储在

1
float

变量中的:

      1. 先来看整数部分,模2求余可以得到二进制表示为110。
      2. 再来看小数部分,乘2取整可以得到二进制表示为.1(如果你不知道怎样求小数的二进制,请主动搜索一下)。
      3. 拼接在一起得到110.1然后写成类似于科学计数法的样子,得到1.101 x 2 2
      4. 从上面的公式中可以知道符号为正,尾数是101,指数是2。
      5. 符号为正,那么第一位填0,指数是2,加上偏移量127等于129,二进制表示为10000001,填到2-9位,剩下的尾数101填到尾数位上即可。
    S E E E E E E E E F F F F F F F F F F F F F F F F F F F F F F
    0 1 0 0 0 0 0 0 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

%title插图%num

内存中二进制数01000000 11010000 00000000 00000000表示的就是浮点数6.5

浮点数的指数位为什么要用移码表示阶码?(移位阶码请看移位操作符)

移码(又叫增码或偏置码)通常用于表示浮点数的阶码,其表示形式与补码相似,只是其符号位用“1”表示正数,用“0”表示负数,数值部分与补码相同。简单来说, 移码就是在原码的基础上加上一个偏移量。

首先,E为一个无符号整数(unsigned int) 这意味着,如果E为8位,它的取值范围为0~255;但是,E是可以出现负数的,所以IEEE 754规定,存入内存时E的真实值必须再加上一个中间数,对于8位的E,这个中间数是127;比如,2e10的E 是10,所以保存成32位浮点数时,必须保存成10+127=137,即10001001。

然后,指数E从内存中取出还可以再分成三种情况:

E不全为0或不全为1
这时,浮点数就采用下面的规则表示,即指数E的计算值减去127,得到真实值,再将有效数字M前加上第一位的1。

比如: 0.5(1/2)的二进制形式为0.1,由于规定正数部分必须为1,即将小数点右移1位,则为1.0*2^(-1),其阶码为-1+127=126,表示为01111110,而尾数1.0去掉整数部分为0,补齐0到23位00000000000000000000000,则其二进制表达式为:
0 01111110 00000000000000000000000

E全为0
这时,浮点数的指数E等于1-127,即为真实值, 有效数字F不再加上第一位的1,而是还原为0.xxxxxx的小数。这样做是为了表示±0,以及接近于0的很小的数字。

E全为1
这时,如果有效数字F全为0,表示±无穷大正负取决于符号位s;

问什么8位阶码的偏置为127 ?

首先,这是IEEE标准规定的,我们必须执行。 其次,我来解释下为什么IEEE标准中,8位阶码的偏置为127。

1、8位移码的取值范围为0~255(00000000~11111111),但在浮点数的阶码中,00000000与11111111被保留用作特殊情况,所以阶码可用范围只有1~254,总共有254个值。

2、8位有符号数取值范围为-128~+127(10000000~01111111),这里的二进制用补码表示,其中特别规定补码10000000没有原码,为-128的补码,总共有256个值。

3、如果采用偏置128,在表达+127时会产生上溢(移码11111111被保留),所以在阶码中偏置为(128-1),与此同时,在表达-127时会产生下溢(移码00000000被保留),所以阶码中去掉-127与-128,取值范围为-126~127,总共254个值。

float范围

明白了上面的原理就可求float类型的范围了,找到所能表示的最大值,然后将符号为置为1变成负数就是最小值,要想表示的值最大肯定是尾数最大并且指数最大,
那么可以得到尾数为 0.1111111 11111111 11111111,指数为 11111111,但是指数全为1时有其特殊用途,所以指数最大为 11111110,指数减去127得到127,

所以最大的数字就是1.1111111 1111111 11111111 x 2127 ,这个值为 340282346638528859811704183484516925440,通常表示成 3.4028235E38,那么float的范围就出来了:

[-3.4028235E38, 3.4028235E38]  有效数7个。

 

Posted in C语言, C语言

发表评论

相关链接