计算机系统基础(四)浮点数

版权声明:本文为博主原创文章,未经博主允许不得转载。

上一讲我们讲解数字用定点数表示的方式,但用定点数表示小数会有2个问题:数值范围有限和精度范围有限,所以在计算机中一般小数使用浮点数表示。这篇文章我们来讲解浮点数的表示。

什么是浮点数

首先我们先来看,什么是浮点数?

定点数的「定点」指的是约定小数点位置固定不变,然后对数字进行表示。那浮点数的「浮点」含义也就容易理解了:在对数字进行表示时,小数点的位置可以是漂浮不定的。

这怎么理解呢?

浮点数采用一种科学计数法的方式表示,如果要表示十进制小数8.345,用科学计数法表示,可以有多种方式:

1
2
3
4
8.345 = 8.345 * 10^0
8.345 = 83.45 * 10^-1
8.345 = 834.5 * 10^-2
...

同样,对于二进制数,也可以用科学计数法表示,把基数10换成2即可。

看到了吗?用这种科学计数法的方式表示小数时,小数点的位置变得“漂浮不定“了,这就是相当于定点来说,浮点数的名字来源。

当然,我们没必要纠结这个名字为什么非要这么起,理解其表示方法才是关键。

浮点数如何表示

上面提到,浮点数是采用一种科学计数法的方法表示,这个表示格式如下:

1
X = (-1)^S * M * R^E

各变量含义:

  • S:取值0或1,决定一个数字的符号,0表示正,1表示负
  • M:二进制定点小数,表示数字的尾数
  • E:二进制定点整数,表示数字的阶码或指数
  • R:基数,可以约定为2、4、16

如果要表示一个浮点数,只需要确定这几个变量即可,假定用32位表示一个浮点数,二进制表示如下:

基数R、阶码E和尾数M的位数,在早期各个计算机厂商是自己定义的,例如IBM在早期定一个32位浮点数格式如下:

  • 基数为16
  • 0位表示符号位
  • 1~7位表示阶码
  • 8~31位表示尾数

如果将十进制数65798转换为IBM定义的浮点数格式,怎么转换?

1
65798(D) = 10106(H) = 0.101060(H) * 16^5

所以S=0,尾数M=0.101060(H)=1 0000 0001 0000 0110 0000。

但这里的阶码E不是5,而是需要用E的移码表示。

为什么要阶码的移码表示?这是因为阶码E可正可负,当进行浮点数加减运算时,必须先比较两个数的阶码大小并使之相等,为了简化操作,在计算时不涉及到符号的运算,故对每个阶码都加上一个正的常数,使所有的阶码都转换为正整数,简化阶码操作。

E的移码=2^n-1 + E,n是阶码的位数,这里n=7,所以E的移码=69(D) = 1000101(B)。

所以最终的浮点格式表示如下:

以上只是一家计算机厂商的自定义格式,其他厂商也可以定义其他格式,我们可以发现一个问题,在表示浮点数时,在总位数不变的情况下,这样产生以下的结果:

  • 阶码位数越多,尾数位越少,表示的范围越大,但精度就会变差
  • 阶码位数越少,尾数位越多,表示的范围越小,但精度就会变好

当时的计算机厂商都对浮点数的表示格式进行了自定义,格式不统一,这样产生的问题就是:

  • 一个数字因为表示格式不同,得到的二进制值不唯一
  • 不同结构的计算机进行数据传输或程序移植时,必须进行数据格式的转换
  • 尾数、基数、阶码位数不同,表示的数据范围和精度不要一定是最有效的

那怎么解决这种问题呢?业界迫切需要一个标准统一浮点数的格式表示。

浮点数标准

直到1985年,IEEE组织推出IEEE754浮点数标准,统一了浮点数表示形式,并提供了2种基本浮点格式:

  • 单精度:32位表示浮点数,第1位表示符号位S,之后8位表示阶码E,最后23位表示尾数M
  • 双精度:64位表示浮点数,第1位表示符号位S,之后11位表示阶码E,最后52位表示尾数M

为了使得表示的数字范围、精度最大化,浮点数标准还对阶码和尾数进行了规定:

  • 尾数的第一位总是1,因此可在尾数中省略第一位的1,这个1称为隐藏位,使得单精度23位尾数表示了24位有效数字,双精度52位尾数表示了53位有效数字
  • 阶码不是用单纯的移码表示,而是在移码的基础上进行偏移修正,因为尾数第一位1在隐藏位中,所以阶码的移码需要加1,即阶码=(2^n-1) - 1

当然,虽然规定了阶码和尾数的位数,但阶码和尾数有几种情况,分别表示不同的值:

  • 阶码非全0且非全1:规格化非0数
  • 阶码全0,尾数非0:非规格化数,尾数隐藏位不再是1,而是0
  • 阶码全0,尾数全0:分别表示+0/-0
  • 阶码全1,尾数全0:正无穷/负无穷
  • 阶码全1,尾数非0:NaN(Not a Number)

浮点数所说的「规格化」就是第一种情况,也是我们最常见的情况,其他情况都是「非规格化」的数字。

浮点数表示

下面我们来看一个十进制数-0.75转换成标准的单精度浮点数是如何表示的。

1
-0.75(D) = -0.11(B) = -1.1 * 2^-1

所以符号位S=1,尾数M=1.1,阶码E的移码修正后=2^7-1-1=126。

尾数小数点前的1为隐藏位,省略不写,尾数二进制表示为100 0000 0000 0000 0000 0000,阶码二进制表示为0111 1110

所以-0.75规格化的浮点数表示为1 0111 1110 100 0000 0000 0000 0000 0000

总结

以上就是浮点数相关知识点,我们总结一下:

  • 浮点数的名字来源是相当于定点数的
  • 浮点数的表示格式最初由计算机厂商自定义,没有得到统一
  • 后来IEEE组织推出浮点数标准,统一了格式,并规定了单精度和双精度浮点数
  • 同时也制定了浮点数的规格化和非规格化格式,用来表示各种数字
  • 浮点数因为范围和精度范围更大,所以在计算机中小数使用浮点数表示

如果此文章能给您带来小小的工作效率提升,不妨小额赞助我一下,以鼓励我写出更好的文章!
kaito-kidd WeChat Pay

微信打赏

kaito-kidd Alipay

支付宝打赏