学习《深入理解计算机系统(第三版)》第二章总结
三种重要的数字表示
- 无符号编码:基于传统的二进制表示法,表示大于或等于0的数字。
- 浮点数编码:表示有符号整数的最常见的方式,可为正或负
- 浮点数编码:表示实数的科学记数法的以2为基数的版本
排列表示一个对象的字节的规则
- 小端法(little endian):某些机器选择在内存中按照从最低有效字节到最高有效字节的顺序存储对象,最低有效字节在最前面的方式成为小端法。
- 大端法big endian):一些机器则按照从最高有效字节到最低有效 字节的顺序存储,最高有效字节在最前面的方式成为大端法。
- 双端法(bi-endian):可以把它们配置成作为大端或者小端的机器运行。然而,实际情况是:一旦选择了特定操作系统,那么字节顺序也就固定下来。
有符号数和无符号数之间的转换
C语言允许在各种不同的数字数据类型之间做强制转换。
强制类型转换的结果保持位值不变,只是改变了解释这些位的方式。
执行一个运算的时候,如果它的一个运算数是有符号的而另一个是无符号的,那么C语言会隐式的将有符号数强制类型转换为无符号数,并假设两个数都是非负的,来执行运算。
整数运算:
①无符号数的加法:
重要结论:模数加法形成了阿贝尔群,可交换结合,每个元素都有一个加法逆元。
②补码加法;
③补码的非;
④无符号乘法;
⑤补码乘法:
重要结论:设为二进制表示的无符号整数,对于任意k0,有以下公式:
即:一个二进制表示数乘以,相当于在位模式右边补了k个0(不溢出的情况),相当于一种移位操作,C表达式中x << k等价于 x * pwr2k,许多C语言编译器视图以移位,加法和减法的组合来消除很多整数乘以常数的情况。
例如:x*14,利用等式14=,编译器将乘法重写为(x<<3)+(x<<2)+(x<<1),实现将一个乘法替换为三个移位运算和三个加法,减少时钟周期提高运算效率。
⑥补码除法:
向零舍入:即乘法的逆运算,执行算数右移k位即除以,因为移位导致结果向下舍入,根据向零舍入的要求,通过偏置, = 可以得到正确的舍入结果。
浮点数的IEEE表示:
① IEEE浮点表示:
-
符号:s通过其值1负和0正决定V的正负,对于V=0另作解释。
-
尾数:M是一个二进制小数,它的范围是1 – 2-ε,或者0 – 1-ε
-
阶码:E的作用是对浮点数加权,权重是2的E次幂(可能是负数)
②通过将浮点数的位划分为3个字段,分别进行编码,类似科学计数法:
-
1个单独的符号位s,直接编码符号s
-
k位的阶码字段,exp=e k-1···e0,编码解码E
-
n位的小数字段,frac=fn-1···f0,编码尾数M,但是该值依赖于E是否为0
③ 浮点表示的三种情况:
-
规格化的值:
普遍情况,当exp不全为0,也不全为1,此情况解码以偏置形式表示有符号整数,即E = e – Bias,e是无符号数,e表示为阶码位的编码ek-1···e0,而Bias是一个等于(单精度k=8,双精度k=11)的偏置值,由此产生指数的取值范围即:(单精度-126~+127,双精度-1022~+1023),对于frac解释为描述小数值f,期中0≤f<1,其二进制表示为0.fn-1···f0,当尾数定义为M = 1+f时,叫做隐含以1开头的表示,所以M = 1.fn-1···f0,因为二进制的基数是2,且我们总能在不溢出的范围内调整阶码,使得尾数M的范围总在1≤M<2中,符合IEEE定义M的范围,从而表示小数。 -
非规格化的值:
当阶码exp域全0,阶码值为E = 1-Bias,而尾数值为M = f,不包含隐含开头都 1(为什么),非规格化的值用来表示0和非常接近0的小数,因为规格化要求M≥1,所以无法表示0,实际上+0.0的浮点表示位模式全0,而当符号位为1时候得到-0.0,逐渐溢出的属性使得数值均匀的接近0.0(?) -
特殊值:
当阶码exp域全1,当frac全0表示无穷,根据符号位的表示的正负来确定正负无穷,无穷能表示溢出的结果,当小数域非零时,NaN被称为不是一个数的缩写,一些运算结果为虚数,无法表示。