【计算机组成原理】2.3.1_2 IEEE 754

2.3.1_2 IEEE 754

00:00

好的,上个小节中我们学习了浮点数的基本构成还有一个原理,浮点数大致上分为阶码,还有尾数这样的两个部分组成。上个小节的末尾我们提到过,如果说我们不能确定一个统一的规则,阶码占多少位,尾数占多少位,各自采用原码、补码还是移码来表示,如果我们不能统一一个规则的话,那么在计算机之间进行数据传输就会出现一些解析方面的困难和问题。所以有这样的一个组织,他定了一个标准叫IEEE754。很多同学不会读这个组织的名字。我们来看一下大家熟悉的王者荣耀这个游戏里边,如果你有双杀的话,他会说double kill对吧?如果三杀的话triple kill,然后四杀quadra,刚才我们念这个IEEE就是把它念作i triple e,其实就是三个的意的意思。好,所以大家要知道我们计算机领域很重要的这个组织的名字,应该怎么优雅的把它念出来,需要学习一下,跟王者荣耀学习。

01:13

由于我们IEEE754的标准当中,阶码是用移码的方式来表示的。所以这儿我们先快速的回顾一下我们之前学习过的移码。之前我们说过移码就是在补码的基础上把符号位取反就可以,并且移码只能表示整数。那我们浮点数的阶码部分也只需要用整数来表示,所以移码的这个特性是能够够用来表示阶码的。好,来快速回顾一下,对于正19这个数,它的补码形式是这样的,那把它的符号位取反就可以得到与之对应的一个移码。-19这个数同样的把它的补码形式的符号位取反,就可以得到与之对应的一个移码。之前我们用这种方式能够比较简单快速的了解移码和补码之间的一个联系。

但事实上如果我们回到移码的定义本身,我们会发现,就是移码最原生的这个定义。我们要确定移码的一个机器数表示是这么来确定的:我们会用二进制的形式写出想要表示的那个数的真值,然后再加上一个所谓的偏置值。像我们之前提到的这个例子当中,我们八位的移码取了偏置值为128,如果用二进制表示,就是一个1加七个0,128也就是2的N减1次方。这儿的N指的是我们移码的总位数,2的7次方等于128。

02:52

好,所以对于真值-127来说,我们先写出它的二进制表示。然后现在我们要求它的移码只需要用这个真值的二进制数,加上刚才我们提出的偏置值,也就是一个1七个0,那这就相当于用128减掉七个一。这个二进制减法很简单,最终减出来的结果就应该是7个0一个1。所以-127这个真值,它所对应的移码就是这样的一个值。

03:24

好,再来看比如说-3,如果我们用二进制表示它的真值,那么是-11,用真值加上偏置值可以得到这个数的一个移码。那这个加法我们可以把它转换成10000000减掉11。那从高位借借一直借过来,然后最后算出来的结果应该是这样的一个数,和我们在补码的基础上把符号位取反所得到的这个移码结果是一致的。好,那剩下的我们就不再一个一个举例,大家可以再试一下。

03:57

总之当我们在确定一个移码的表示方案的时候,其实我们首先要确定的是一个偏置值。我们需要在二进制数的真值基础上加上这个偏置值,就可以得到基于这个偏置值所对应的移码。一般来说偏置值我们都会取2的N减1次方。基于这种方案,我们得到的移码刚好就可以呈现出之前提到的这种规律,就是只需要在补码的基础上符号位取反,这样就可以。好,这是普通的情况。

04:32

但是也有时候我们可以把偏置值设为不一样的值。比如这个小节要学习的IEEE754,它的阶码是用移码来表示的,只不过它规定偏置值不是128,而是127,也就是2N-1-1。如果用二进制表示的话,就是一个0加七个1好。所以基于这个新的偏置值,我们来看一下,对于真值-128来说,我们先写出它的二进制形式,然后加上这个偏置值。那这个地方大家会发现,我们偏置值的绝对值比-128的绝对值要更小。

05:19

那这个加法操作怎么做呢?被减数要比减数更小。但是由于我们这个移码的位数只有8比特只有八位,所以所有的这些加减运算其实在背后都默认了会进行模二的8次方,会有这样的一个隐含的条件。所以之前我们简单的介绍过模运算:当我们在模2的8次方这个条件下进行加减法的时候,我们可以在原有的这个基础上再加上一个2的8次方,也就是一个1八个0,加上这样的一个值之后,整体的这个减法得到的结果是不会变的。所以被减数加上一个18个0,那么得到的结果就是一个1,然后再加上刚才的这个被减数,那当我们加上这个模数之后,是不是就可以保证被减数现在是比减数更大的?

06:14

好,接下来我们就可以用大家熟悉的那种减法运算的规则来计算它的一个值。 1减0等于一,后边的这几位全部都是一,然后到最高位这个地方是0,需要向高位借一个一,2减1剩一个1。所以-128它的二进制真值加上我们的偏置值,最终得到的结果就是八个1。因此如果我们的移码偏置值等于127,那么-128这个真值所对应的移码刚好就是八个1。接下来-127,它的二进制真值应该是负的七个1。那这个真值加上偏置值刚好就可以得到8个0。因此-127它所对应的移码就应该是八个0。好,其他的这些真值也是一样的,大家可以自己再验证一下。

07:12

总之当我们把偏置值从2n-1次方变成2n-1-1之后,相当于从我们之前熟悉的这种移码做了一个减一的操作,在这个基础上减一的操作,所以你看和之前的这种移码的编码方案相比较,它们之间就只差一格。另外我们最小的两个负数,也就是-128和-127,刚好对应两个很特殊的状态,全一和全0。如果把这8个比特看作一个无符号数,那么所有的数都是1,这对应无符号数的255,然后-126这个数它所对应的移码如果把它看作无符号数,那么应该是无符号数的1,从无符号数的1一直到无符号数的254,这整个范围无符号数的数值越大,那么与之对应的这个移码的真值也是越大,就逐步递增的。好,这个地方大家需要注意全1和全0这两种比较特殊的移码状态。

08:23

好,那么在回顾了移码之后,我们接下来正式的开始学习IEEE754标准。它所规定的浮点数的一个格式,分为短浮点数、长浮点数和临时浮点数。C语言里边的float型变量,它就遵循了这个标准所规定的短浮点数的一个要求。然后C语言里的double类型就是对应了这个标准里边所规定的长浮点数。然后还有一个大家可能没有用过,就是C语言里的long double这个类型对应的是临时浮点数类型。从上至下,这些浮点数的长度会越来越长,短浮点数总共只需要32个比特位,其中最高位的是数符,就是表示了整个浮点数的一个正负性。然后接下来的8个比特位表示的是阶码。刚才我们说过阶码是用移码来表示的,并且在这里边移码的偏置值它是规定了是127,而不是我们之前熟悉的128。

09:32

除了数符和阶码之外,末尾还有23个比特位是表示尾数。值得注意的是尾数是用原码来表示的,而上一小节我们举的那些例子,尾数都是用补码来表示的,那我们之前说过,对于一个浮点数来说,如果它的尾数是用原码表示,那我们会希望它的第一个有效的数值位是1对吧?也就是所谓浮点数规格化的问题。那我们干脆可以默认就是在这一部分尾数之前,我们让它隐含了一个最高位的1,这样的话就免去了我们必须要规格化这样的一个步骤。

10:15

所以虽然这个短浮点数它的尾数只有23位,但事实上它应该总共是有24位有效位。因为我们默认了前边隐含了一个1,然后1. 后面加上这个M才是这个尾数真正表示的一个数值。好,所以这一点在做题的时候需要注意,我们需要在尾数前边加上一个1,然后小数点是跟在这个1的后面。

10:42

好,除了尾数之外,刚才说过阶码是用移码来表示的,移码的偏置值和我们之前熟知的2n-1这种偏置值不一样,还要再减一个1,好,另外上一页PPT里边我们说过八位的移码可以表示的范围应该是负的128一直到正的127,对吧?但是当偏置值为127的时候,-128和-127这两个数它们的移码表示会比较特殊,一个是全0,一个是全1。在754标准中,我们会把阶码全一和全零这两个状态作为一个特殊的用途。所以事实上八位的阶码,正常来说它的真值的范围应该只会取到负的126到正的127。因为全1对应-128,全0对应-127,这两个状态我们会用作特殊的处理。那具体怎么特殊,我们之后再来补充。

11:49

我们现在先来看我们有可能会遇到的正常情况。对于这个表里边给出的每一种浮点数,每一种浮点数数浮阶码尾数各自占多少位,这一点大家一定要记住,考试的时候不会告诉你说短浮点数它的格式是1加8加32,这个是需要大家自己记住的。好,我们来看一个比较直观的例子,短浮点数它最开始的这一位是数符,就是表示整个数值的正负性。然后接下来的这八位表示的是阶码,那这个阶码是用移码的方式来表示的,那之前我们说过移码的定义是这样的,移码 = 真值 + 偏置值。所以基于这个定义我们可以得出这样的结论,我们要确定阶码的真值,那阶码的真值 = 移码 - 偏置值。那对于短浮点数来说,就是要减掉127。

12:52

好,因此短浮点数它的真值应该是多少呢?首先是用这个符号位确定它的正负性,然后尾数应该是1 . 再加上这后边的23位,最后再乘以2阶码- 偏置值这么多次方,这就是短浮点数的真值的一个确定方式。一会儿我们会用一个具体的例子带大家来练习。

13:18

好,接下来再看double型的浮点数,这种浮点数它的总位数要比单精度的要多一倍,总共有64位。它最开始的这一位是符号位,接下来的这11位表示的是阶码,然后再往后还有52位表示的是尾数。同样的我们需要在这个尾数的前边加上一个1 . ,由于阶码总共有11位,所以长浮点数或者说这种双精度浮点数,它的偏置值应该是211-1-1,也就是1023。

14:03

如果用二进制来表示的话,1023我们可以把它写成一个0加上十个1,这就是1023的一个二进制表示。所以如果我们要确定长浮点数它的阶码的真值是多少,那我们需要用这蓝色部分的移码减掉我们刚才提出的这个偏移量,偏置值,我们计算的时候可以把移码部分,还有这个偏置部分把它们看作是无符号数,就是把这些二进制转换成无符号数再来进行相减的操作,没有必要说一定要用两个二进制数相减。就比如在这个例子当中,移码我们如果把它看作无符号数的话,应该是应该是16加4再加8就应该是28对吧?这是移码看作无符号数的一个值。那28再减掉我们的偏置值1023,那就应该等于负的多少大家可以自己算一下,这就是这个阶码的真值。

15:13

好,总之这儿想强调的是,我们在实际计算的时候,可以把这个移码先把它看作是无符号数,把它转换成十进制,然后再来减掉我们的偏移量。这样要比直接用二进制来进行减法会更简单一些,也更不容易出错。好,和短浮点数的真值确定方式也是类似的。长浮点数的真值我们就是首先根据符号位确定整体的一个正负性,然后尾数应该是1 . 加上后边的这52个比特的信息,然后再乘以2阶码-1023这样的一个值,这就是长浮点数的真值。

15:53

好,接下来我们以短浮点数,也就是单精度浮点数为例来进行一个练习。我们要把十进制的-0.75转变成754标准规定的单精度浮点数的类型,应该是1加8加23,一位数符、8位阶码,然后23位尾数。好,首先我们把这个十进制数先把它转换成二进制的形式,应该是-0.11。由于我们尾数部分最高位隐含为1,所以我们必须对刚才得到的这个二进制数进行一个规格化,就是让小数点前边这一位让它变为一。这样的话才可以和我们隐含的这个高位1进行一个对应。所以负的0.11我们可以把它看作是负的1.1再乘以2-1次方,乘以2-1就意味着小数点要前移一位.

16:54

这样的话我们就完成了规格化。由于这个数它是一个负数,所以数符我们需要取1表示负。另外尾数部分应该是一个1,然后后边的几位全部都是零。因为我们在高位已经隐含了一个1,所以再补上高位。那个一就应该是1.100000,和我们这儿规格化得到的尾数是能够对应上的。

17:21

好,那确定了数符和尾数之后,需要再确定阶码。那阶码的真值应该是-1,而单精度浮点型它的偏移量应该是127,所以我们的移码可以用阶码的真值加上这个偏移量,进行一个相加的操作,然后就可以得到移码的一个表示。

17:44

这儿我们是直接用二进制数相加,但事实上和之前一样,我们也可以直接用十进制相加,然后再把十进制转换成对应的二进制无符号数。所以127加上-1等于126,那126它所对应的无符号数就应该是这样的一个值。所以看大家自己的习惯,你也可以直接用这个十进制计算,然后再把十进制转换成与之对应的二进制,只不过是需要把它看作是无符号数,并且总共占8个比特。好,那到此为止我们就确定了数符、移码还有尾数分别应该为多少,把它们拼起来总共凑足32位,这就是用754这个标准的单精度浮点数来表示的-0.75这个值。这个例子是从十进制转换成浮点数。

18:42

接下来我们再来看一个逆过来转换的例子。这儿给出了一个单精度浮点数,用16进制表示,然后问我们它所对应的十进制真值是多少?好,来看一下,我们先把这个16进制数,先把它转换成与之对应的二进制。那十六进制转二进制。不熟悉的同学可以暂停下来自己练练手。

19:05

好,最开始的一位是数符,接下来的八位是阶码,然后再往后的23位是尾数。我们把这三个部分分开来分析。首先数符=1,说明这是一个负数。接下来尾数部分应该是 . 01,然后后续都是0,在这个尾数之前还隐含了一个最高位1,所以尾数它所对应的真实的值应该是1.01,需要在小数点前面补一个1。

19:34

再来看阶码部分,阶码是用移码的方式来表示的,是这样的一个值。如果我们把它看作是无符号数,就应该对应129这样的一个值。那由于单精度浮点数的偏移量或者说偏置值是127,所以阶码所对应的真值就应该是移码 - 偏移量或者说偏置值也就是129 -127等于2,因此阶码对应的真值就是十进制的2,所以整个浮点数的真值就应该是二进制的-1.01乘以2的2次方,也就是小数点往后移两位,当然也可以先把前面这个二进制数先给转换成十进制,应该是对应十进制的-1.25,然后再乘以22,也就是乘以4。那么相乘之后得到的结果就应该是负的5.0,因此我们刚开始给出的这个单精度浮点数,它所对应的真值应该是十进制的-5.0。

20:39

好,通过这两个例子,大家对这三个部分的作用还有处理应该能有一个初步的认识。接下来我们再来探讨这样的一个问题,就是对于单精度浮点型来说,我们所能表示的最小绝对值和最大绝对值应该是多少呢?首先需要注意到尾数部分,我们说过它的最高位隐含了一个1对吧?所以尾数部分我们要取绝对值最小的话,就应该是取全0,而尾数全零它实际上所对应的真实的值应该是二进制的1.0,就是高位的一是原本就隐含的,这是尾数所能表示的最小的一个绝对值。

21:22

好,接下来我们要让整体的绝对值最小,那我们是不是需要让这个阶码它的真值也最小?而之前我们说过,虽然阶码是用移码表示,理论上我们可以表示-128到127这样的一个范围的数。但是-128、-127对应的全1和全0,我们会用来作为一个特殊的用途,因此阶码的真值可以表示的最小值就应该到了 -126,那 -126它所对应的移码机器数就应该是这样的一个值,00000001,那1.0这样的一个二进制数乘以2-126,就意味着我们需要把这个小数点往前移126位,所以这就是单精度浮点数它所能表示的一个最小的绝对值。

22:20

接下来再来看最大的绝对值。显然我们需要让尾数的绝对值也最大,然后阶码的真值也达到最大,所以我们应该让尾数全为1,然后再乘以2127次方,是阶码所能表示的最大的一个正值,也就是说在1点23个一的基础上,小数点往后移127位,这就是单精度浮点数所能表示的最大的一个绝对值。好,那类似的对于双精度浮点数,它的最小绝对值和最大绝对值也可以用一样的方法来分析。只不过是尾数还有阶码所能表示的最大和最小值发生了一些改变而已,原理都是类似的,所以这就不再赘述。

23:04

好的,既然单精度浮点数它所能表示的最小绝对值只能到这样的一个数,那接下来我们来思考这样的一个问题。如果现在我们要表示的这个数值,它的绝对值比我们这儿推出的绝对值还要更小,那怎么办?有没有可能表示比这个绝对值还要更小的数呢?好,其实是有可能的。在这个地方我们就会用到之前提到的阶码全1或者阶码全0这样的两个状态。

23:35

对于单精度浮点数来说,阶码总共占八个比特。如果把它看作是无符号数,那么它所能表示的范围就应该是0到255,对吧?零这个无符号数对应的刚好就是全零的一个二进制,255所对应的无符号数就刚好对应了全一。所以刨除全零和全一这两个状态,当我们的阶码部分,它的值小于等于254,大于等于一。当它处于这个区间的时候,才是我们之前所探讨的那种正常的区间。当然这个地方我们对解码的解读是把它看作是无符号数,并不是说它的真值落在这个区间,这个大家不要混淆。

24:20

好,当我们的解码不是这两种特殊状态的时候,用之前我们提到的这种方式就可以确定这个单精度浮点数它的一个真值到底是多少。好,接下来如果阶码不在这个范围,如果它是全零的话,那在阶码为全0,并且尾数M不全为0的时候,我们表示这是一个非规格化的小数。在之前的讲解中我们都是默认高位是隐含了一个1。但是如果阶码全为0的话,那我们会认为这个小数点前边的一位就是零。在这种情况下,这个浮点数它所对应的真值应该是0.M乘以2-126次方。

25:11

如果我们要表示的数值比之前我们推出的这个最小绝对值还要更小。比如说我们要表示0.001乘以2的负126次方。如果要表示这个数值的话,那我们可以这么做,我们可以让这个阶码部分全部为零,都为零。然后尾数部分我们存入的应该是001,然后后续也都是零。最高位的这个零是隐含的。好,另外由于这个数它是一个正数,因此数符这个位我们应该存零,表示这是一个正数。

25:51

好,所以如果引入了这个阶码全为零这样的特殊状态,我们就可以用单精度浮点数来表示比我们之前提出的这个绝对值还要更小的一些数。那在这种规定下,这个小数的最高位它不是一不是一个有效值,所以这种小数就是非规格化的小数。而之前我们提到的就是普通的情况,最高位都是一,都是规格化的小数。好,这是一种比较特殊的约定,需要注意当阶码E全为零的时候,我们补充的这隐含最高位就变成了0。

26:30

另外乘以二的多少次方,这个地方会固定为负126次方。虽然说在偏置值等于127的情况下,移码全零这个状态,事实上是对应负的127次方,对吧?这是我们之前推出的一个结论。但是这个地方我们会固定的把它视为乘以2的-126,而不是127。所以在这种特殊状态下,我们确定这个阶码的真值的时候,就不是用之前提到的那种方式来进行转换了,这就是一个死的规定。

27:05

好,再看下一种特殊的情况,如果阶码全为零,并且尾数也全为零,那在这种情况下就是用与表示真值的0。当然浮点数里边真值零也可以有正零和负零这样的两种状态。具体是正零还是-0,其实就是看数符位它到底为零还是为一好。总之如果用浮点数表示真值0,那么阶码和尾数部分都是零。好,这是阶码全0的时候的一个特殊的用途。

27:37

接下来再看阶码全一的时候,如果阶码全为一,也就是说对应无符号数的255这个状态的话,那么此时如果尾数M全为零,那我们会用这种状态来表示无穷大,有可能是正的无穷大,有可能是负的无穷大。那到底是正是负,同样的也是看数符部分。当我们对两个浮点数进行加法或者乘法之类的运算的时候,如果说发生了正上溢或者负上溢,那么机器通常会把计算的结果记录为正无穷大或者负无穷大。有了这样的记录,接下来就可以方便我们对这种异常状况进行处理。好,这是阶码全1尾数全0的时候的一个特殊的约定。

28:23

再来看如果阶码全1而尾数不全为0,那这种情况是表示一个非数值数NaN,指的是not a number。什么时候会用到它呢?如果我们非法的进行了,比如0除以0或者无穷减无穷,进行了这种非法的操作之后,这种运算在数学上是非法的,所以如果进行了这种非法运算,那么计算机会把这个非法运算的结果用一个浮点数NaN这个类型的浮点数来记录。同样的有了这样的记录之后,才可以更方便我们对这种异常情况进行后续的处理。

29:06

好,所以当阶码全1或者全0对应无符号数255和0这两种状态的时候,我们对这个浮点数的解读规则是会有一些特殊的规定的。

好的,这个小节中我们介绍了IEEE754这个标准所规定的短浮点数、长浮点数,还有临时浮点数它们的一个基本结构。我们举的例子主要是基于短浮点数来进行举例,但是长浮点数还有临时浮点数,它们的分析方法也是一样的,只不过是阶码尾数这些数值部分,它们的比特位发生了一些变化而已。

29:51

无论是哪种类型的浮点数,我们都需要记住尾数部分是用原码表示的。同时我们会规定在正常情况下,我们在高位是隐含了一个1的。也就是需要在这个尾数的前面加一个小数点,然后再加一个一,这才是尾数真实的一个值。

30:09

另外阶码部分采用移码表示,只不过这个地方的移码它的偏置值和我们之前熟悉的2n-1不一样。在这个标准当中偏置值都是2n-1-1。那只有我们记住了这个偏置值是多少,我们才可以确定一个阶码的真值到底是多少。确定的方法就是把移码看作一个无符号数,先把它转换成十进制,然后再减掉偏置值。这样一相减,我们就可以确定阶码的真值到底是多少。确定了解码的真值,然后在这个尾数前边补了一个1,之后再结合数值位所反映出来的正负性,我们就可以确定整个浮点数的真值是多少。

31:00

再次强调阶码全一和阶码全0的时候会用作一些特殊的用途。考试的时候如果让大家对浮点数的值进行转换的话,一般来说不会给你阶码全1和阶码全0的情况,所以重点还是要掌握我们讨论的这种普通情况如何转换。好的,以上就这一小节的全部内容。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值