Chapter2 信息的表示和处理
1.将一个十进制的数字x转换为n进制,可以用n反复除x,得到商q和一个余数r,然后用这个r作为最低位数字,反复这个过程直到商为0,则可以得到n进制的表示,其原理为:
x = a0nm + a1nm-1 +···+ amn0
2.每台计算机都有一个字长(word size),指明指针数据的标称大小。因为虚拟地址是以这样的一个字来编码的,所以字长决定的最重要的系统参数就是虚拟地址空间的最大大小。也就是说,对于一个字长为w位的机器,虚拟地址的范围为0~2w-1
3.小端法:最低有效字节在最前面的方式;大端法:最高有效字节在最前面的方式。如何判断?
#includetypedef unsigned char *byte_pointer;void show_bytes(byte_pointer start, size_t len) { size_t i; for(i = 0; i < len; i++) printf(" %.2x", start[i]); printf("\n");}
4.左移和右移
(1)左移k位:丢弃最高的k位,并在右端补k个0
(2)右移分为逻辑右移和算数右移:
1)逻辑右移k位:左端补k个0,抛弃最低的k位
2)算数右移k位:左端补k个最高有效位的值,抛弃最低的k位
5.整数的表示
(1)无符号编码可以定义为一个映射B2Uw:{0, 1}w → { 0, 1,···, 2w-1 }
(2)补码编码可以定义为一个映射B2Tw:{0, 1}w → { -2w-1,···, 2w-1-1 }
(3)两种编码方式都具有唯一性(双射)
6.有符号数和无符号数之间的转换
处理同样字长的有符号数和无符号数之间的相互转换的一般规则是:数值可能会改变,但是位模式不变。记U2Bw和T2Bw将数值映射为无符号数和补码形式的位表示,则对于0 ≤ x ≤ 2w-1范围内的一个整数x,U2Bw会给出x的唯一w位无符号表示,T2Bw同理。
(1)补码转换为无符号数,对于TMinw ≤ x ≤ TMaxw的x,有
T2Uw(x) = x + 2w, x < 0; x, x ≥ 0
(2)无符号数转换为补码,对于0 ≤ x ≤ UMaxw的x,有
U2Tw(u) = u, u ≤ TMaxw; u - 2w, u > TMaxw
(3)当一个运算数是无符号的时候,另一个运算数也被隐式强制转换为无符号
(4)当一个有符号的short型转成unsigned int时,会先改变大小,再完成有符号到无符号的转换
7.扩展一个数字的位表示
(1)有符号数:符号扩展,即按最高有效位的值扩展
(2)无符号数:零扩展,即扩展位均为0
8.截断数字(截断为k位)
(1)有符号数:x' = U2Tk(x mod 2k),即x先看做无符号数,取模后再转换为有符号数
(2)无符号数:x' = x mod 2k
9.整数运算
(1)无符号数加法:对于满足0 ≤ x, y < 2w的x和y有
x + y = x + y, x + y < 2w; x + y - 2w, 2w ≤ x + y < 2w+1(算数溢出)
(2)有符号数加法:对于满足-2w-1 ≤ x, y ≤ 2w-1-1的x和y有
x + y = x + y - 2w, x + y ≥ 2w-1(正溢出); x + y, -2w-1 ≤ x + y ≤ 2w-1-1(正常); x + y + 2w, x + y < -2w-1(负溢出)
总结:整数加法运算溢出时,采用截断策略
(3)补码的非:对于满足-2w-1 ≤ x ≤ 2w-1-1的x,其补码的非由下式给出
-x = -2w-1, x = -2w-1; -x, x > -2w-1
实际上,-x与~x+1得到的结果一样
(4)无符号数乘法:对于满足0 ≤ x, y < 2w的x和y有
x * y = (x * y) mod 2w
(5)有符号数乘法:对于满足-2w-1 ≤ x, y ≤ 2w-1-1的x和y有
x * y = U2Tw((x * y) mod 2w)
总结:整数乘法运算溢出时,同样采用截断策略
10.乘以常数
大多数机器上,乘法指令相当慢,需要10个或者更多的时钟周期,比移位和加法的代价要大得多,编译器会试图以移位、加法和减法的组合来消除很多整数乘以常数的情况,如将a × 14表示为(a << 3) + (a << 2) + (a << 1)
11.除以2的幂
(1)规则为:向下舍入一个正值,向上舍入一个负值
(2)无符号数就是简单的算数右移操作。而有符号数的除法,对于x ≥ 0,效果与逻辑右移相同;对于x < 0,使用(x + (1 << k) - 1) >> k产生结果,从而得出符合(1)中规则的结果
12.浮点数
(1)IEEE浮点数的表示:V = (-1)s × M × 2E,这里s为符号位,决定数是负数(s = 1)还是正数(s = 0);尾数M表示一个二进制小数,范围为1~2-ε(规格化)或0~1-ε(非规格化);阶码E的作用是对浮点数加权
(2)32位浮点数包含:1位符号位 + 8位阶码 + 23位尾数;64位浮点数包含:1位符号位 + 11位阶码 + 52位尾数
(3)阶码的值决定了这个数是规格化的(不全为0)或非规格化的(全为0)或特殊值(全为1)
(4)非规格化的浮点数表示0或接近0的数
(4)对于规格化的浮点数,阶码的值是E = e - Bias,这个Bias为一个偏置值2k-1-1,且总能通过调整E,使得尾数是以1开头的,也就是1.fn-1fn-2...f0,这样做可以省去表示1的那位,可以多表示一位精度
(5)对于非规格化的浮点数,阶码的值是E = 1 - Bias,不用-Bias表示是因为用1-Bias可以和规格化浮点数对接起来,实现平滑的转变;尾数没有隐藏位,因此是从0开始到1-ε