理解浮点数的二进制表示

目录

 

二进制的科学计数法

浮点数的二进制表示

符号位、尾数和指数(以64位浮点数为例)

0、规约数和非规约数

无穷大和空值NaN


二进制的科学计数法

       浮点数在电脑中用二进制储存,约定以二进制的科学计数法来进行表示一个浮点数,类比十进制的科学计数法,很容易知道,二进制的科学计数法的首位数字一定为1,然后通过乘以相应的底数为2的指数来得到二进制数,如下所示。

       下面等号左边是原二进制数,右边就是其二进制的科学计数表示。和十进制一样,二进制的科学计数表示之后,也具有有效数字(尾数)、底数和指数,只是二进制的有效数字由0和1组成,底数为2。

1110011=1.110011\cdot 2^{6}

浮点数的二进制表示

       所以,浮点数的二进制表示包括符号、尾数和指数。比如对于32位浮点数来说,1位符号位、23为尾数位和8位指数位;对于64位浮点数来说,1位符号位、52位尾数位和11位指数位。尾数以二进制的科学计数法约定表示,因为对于所有约定的规约数来说,首位都是1,所以首位的1会被默认省去,所以对于64位浮点数,其有效精度可以达到二进制的53位;指数的底数为2,由于为了表示小数,故指数也有正负,为了表示负数,所以指数通过移码的方式进行转化。

       以64位浮点数为例,如下所示。从0-63共有64个bit,其中首位用来表示符号,0为正,1为负。接下来11位bit用来储存指数,剩下的52位用来储存尾数。

符号位、尾数和指数(以64位浮点数为例)

       符号位很简单,就是约定0表示正,1表示负。对于尾数,其有52位bit,但是根据二进制的科学计数法,首位都为1,因此我们可以省略掉这个1,这样子52位都可以用来储存尾数的小数部分,因此实际上52位尾数小数的有效尾数有共有53位,只是首位的1被省略了。对于指数,有11bit,但是为了表示负数,采用二进制指数值-偏移量的计算方式得到计算中的指数值;比如64位的指数偏移量约定为1023,11bit可以表示的值的范围为0~2047的整数,但是这里真正被用作指数计算的只有1~2046,0和2047这两个数字被剔除,以用来表示特殊值,这个文章后面再说明;因此,1~2016减去偏移量1023后,真正的指数取值范围为-1022~1023。所以64位浮点数的具体的二进制表示方式如下。

       

0、规约数和非规约数

       So far so good! 问题来了,怎么表示0?由于上述定义中,尾数始终是大于1的,所以无论如何也无法得到0,因此0这个需要特殊定义。根据上述的定义,即指数范围在1~2046之间,有效数字首位为1的浮点数,叫做规约数(normal numbers)。同时还注意到,上述在讲指数的时候,有两个值是没有用到的,即0和2047,对应着指数部分11个bit分别全部为0和全部为1的情形。所以为了表示0,约定当指数部分全部为0,且尾数小数部分也全为0的时候,表示0;要注意的是,虽然本文这里说的是尾数的小数部分全为0,但是实际上这时,首位隐藏的1变成了0。

       接下来的问题是,如果指数部分全为0,但是尾数的小数部分不全为0,这时该表示什么?因为对于规约数的定义,我们研究指数部分的值在1~2046之间,而指数为0时,就超出了规约数定义的范围了,因此,当指数为0,但是尾数小数部分不全为0时,我们定义这样的数为非规约数(denormal numbers or subnormal numers)。要注意的是,非规约数的指数一定是为0的,但是这时偏移量变成了1022;即当指数为0时,那么不仅尾数首位隐藏值从1变成0,而且约定偏移量这时为1022,即移码后的指数依然保持-1022不变(注意不是-1023),以该移码后的指数(即-1022)去计算非规约数的大小。

无穷大和空值NaN

       至此,我们还有一个数没有说明,那就是指数的2047,即指数全为1时的情形。我们约定,当指数全为1,且尾数小数部分全为0时,表示无穷大,然后根据符号的不同,有正无穷大和负无穷大。但是当指数全为1,但是尾数的小数部分不全为0时,表示什么呢?这样的数字实际上是未定义的,所以约定其为NaN(Not a Number),所以可知,实际上NaN的情形是很多的,在对NaN进行比较时,系统约定其是不相等的,因为我们不能通过等号来判断NaN值,由于NaN实际上也有有二进制表示的,所以其不是一个空对象,也不能用是否为空对象来判断;这也是为什么pandas中判断一个值是否为NaN需要使用规定的函数,不能直接使用等号判断和空对象判断的原因,具体的pandas中的判断方式可以看这篇文章

猜你喜欢

转载自blog.csdn.net/S_o_l_o_n/article/details/106438708