计算机系统第二次讨论选题3
计算机系统第二次讨论课选题3

什么是IEEE
我们先不给出冗长的IEEE的定义,而看待这个问题:在计算机中如何表示浮点数?
我们在内存中用连续的32位来表示一个int型的整数,自然而然的就想到也用这种方式来表示小数,并增加一个相应记录小数点位数的寄存器。举个例子:
\(1.5\ 可以用\ 1.1_{(2)}来表示,也就是小数点后面的2的幂次依次减1,即1.1_{(2)}\ =\ 1\times2^{0}\ +\ 1\times2^{-1}\ =\ 1.5_{(10)}\)
这种表示方式往往会比较浪费,并且我们不好确定小数点的位置,表示的范围很受局限,比如如果整数部分与小数部分是16与16对分的话,那么最大的数也才是\(2^{15}\)。
于是有天才研发出了IEEE表示标准。以float浮点数为例,仍旧是利用32位的内存来表示小数,但是它更优雅更明了。
在IEEE中,浮点数有一个数学表达式:\((-1)^sM2^E\),其中M是小数,E叫做2的幂次,范围在[1.0,2.0),当然这个数学表达式怎么搞我会后面讲解。
IEEE标准将32位的存储空间分成三个部分,最高位是符号位,表示正负用的也就是\(s\)。再向后8位叫做阶码位,再向后的23位就是真正存储的有效位。其中单精度也就是float规定了阶码位是8位,双精度的阶码位是11位。为了能让数学表达式表示小数,IEEE中还有一个偏差Bias,其中\(Bias\ =\ 2^{k-1}\ -\ 1\),k就是阶码位的位数。
举例
float test = 15123.0f;
让我们用15123这个数进行举例子。
首先为了在机器中表示,我们将其转化成二进制\(15123_{(10)}\ =\ 11101100010011_{(2)}=1.1101100010011_{(2)} \times 2^{13}\)
让我们做一个小学生游戏----与IEEE中提供的那个数学表达式进行对比:
那么现在我们至少可以确定在CPU中的首位是0,因为15123是一个正数。
那么阶码位呢?前面我们提及了\(Bias\),并且说了它与阶码位有一定的联系。在IEEE中阶码位=\(Bias + E\)。 不要问我为什么,这是IEEE中的规定,所以这个数的阶码位是\(127 + 13 = 140\),转为2进制位\(140_{(10)}\ =\ 10001100_{(2)}\)。
剩下的就是真正的存储有效位。还记得M吗,我们在IEEE中规定了M一定\(≥\)1,那么IEEE中就将这一位缺省并只将剩下的小数点后面的位放入内存中存储,不够的话补0.
那么现在我们就明了了,float15123在内存的存储是:
0 10001100 110110001001100000000 #用空格隔开了表示上面所说的三部分
PS:其实到这里,我们应该能够得出来float的范围是\(2^{-128}\ - \ 2^{128}\) ,注意我们只能说范围
GDB单步汇编调试验证如下:
#include <stdio.h>
int main(){
float f = 15123;
printf("%.12f",f);
return 0;
}
我们可以查看\(f\)临近的4个字节,不妨先来预测一下这4个字节会是什么内容。我们的机器都是小端法存储,而机器打印出来的会是内存地址从从小到大的顺序。于是我们15123对应的2进制从高向低看
首先的第四个内存地址存的应该是\(01000110,对应16进制就是0x46\),第三个内存地址存的应该是\(01101100,对应16进制就是0x6c\),第二个内存地址应该存的是\(00100110,对应16进制就是0x4c\),第一个内存地址内是0。
接下来就是见证奇迹的时候:

为什么有些正整数不能精确表示?
把目光再次放到表达式\((-1)^sM2^E\)上,\(M\)是一个小数并且它的小数位是23位,我们之前说过,那么它的小数部分最小就是\(2^{-23}\)。我们可以想象,当\(E≤23\)的时候,每当M的小数位相对性地”增“1的时候,我们都会在M的小数位中找到唯一一个与之对应的幂次\(E'\),使得\(2^{E'}\ \times\ 2^{E}\ =\ 1\)。也就是说此时每当M加1,确实是可以进行精确表示的。
这段不好理解,我举个例子。
设我们所需要表示的正整数为\(C\).
比如当\(E=14\)的时候,如果要求\(C\)是正整数,那么就要求小数点往后从第15位开始全部是0.那么如果我们需要对于\(C\)加1操作,那么必然是在小数点从前向后数第14位\(+1\),记作\(C_{14}\)。假设之前\(C\)是一个偶数,也就是说\(C_{14}=0\),那么如果我们对\(C\)加一,那么对应\(C_{14} = 1\),要将它换成十进制的时候就是\(2^{-14}\),当然它还需要与\(2^E\)相乘,这里的E是14,也就是得到1。依次类推,知直到\(E = 23\)的时候我们仍然可以这样依次加1的方式来精确地表达整数。
当\(E>23\)的时候,不妨取E=24,就算是M的最低位增1,那么也是\(2^{-23}\ \times\ 2^{24}\ =\ 2\),即增加的是2,也就是中间的从该数增1的整数不能正确表示。
综上所述,我们可以知道不能精确表示的最小正整数是\(2^{24}\ +\ 1\ = \ 16777217\)
计算n阶码,m位尾数不能精确表示的最小整数
套公式就好了。基于上面的分析可知是\(2^{m+1}+1\)。

浙公网安备 33010602011771号