听课笔记CSAPP
概述:这里是csapp2015 fall 听课中的一些笔记。
lecture2
二进制中位的下标,构成的集合
例如:01101001 ,从右到左边下标从0 ~ 7,其中值为 1 的有,{0,3,5,6},这些下标构成一个集合。
下面我们看看这个集合的一些运算,首先给出两个二进制数字如下 a = 0b01101001 和 b= 0b01010101;
将这两数字映射为集合得到 a1 = {0,3,5,6} 和 b1 = {0,2,4,6}
依此类推:可以得到 | 对应集合中的 并运行 ; ^ 得到两个集合中不同的部分;~ 取补集
位移
只有一种左移,但是有两种右移,分为逻辑右移和算术右移。
左移:低位补0
逻辑右移:高位补0
算术右移:高位补符号位
数字范围
无符号数: 0 ~ 2w−12^w -12w−1
Two’s complement : −22−1-2^{2-1}−22−1 ~ 22−1−12^{2-1}-122−1−1
下面这张ppt将映射关系画了出来:
注意:运算中有一个是无符号数,那么另外一个数也会转换成无符号数进行比较,<,>,==,<=,>= 这些符号如果使用不当,会有意外的bug出现。
∣TMax∣+1=∣TMin∣
|TMax| + 1 = |TMin|
∣TMax∣+1=∣TMin∣
UMax=2TMax+1UMax = 2 TMax + 1
UMax=2TMax+1
第一个公式,可以看出在补码中的数字表示是不对称的,因为有0的存在;
第二个公式,从原理上理解会清晰,TMax的最高位(符号位)不是1,其余位都是0,UMax是全部为1;2TMax将二进制数字向左移动了一位,+1 是为了将移出来后最低位的0变成1.
bug
int i;
for(int i=n-1;i-sizeof(char)>=0;i--)f(a[i]);
sizeof返回的 unsigned 类型,运算会自动转换成 unsigned,然后会一直大于0,这样这就是一个死循环。
扩展/截断 位数
无符号数,扩展的时候,高位补0;补码在扩展的时候,高位补符号位;
为什么高位补符号位会对数字的大小没有影响?
扩展一位是这样,扩展多位的时候,依次类推就好。
我们基于这样的原理,能得到很好的结论,当我们看到一堆类似ffff…0123 前面的一堆f只是想告诉我们这是一个负数。
截断
无论是无符号数还是补码,当截去最高位的时候,值的变化都相当于减去最高位。
但是补码有一种情况下是值不变的,那就是最高位为1,最高位的下一位也是1的时候。
大家可以想想为什么?