CSAPP读书笔记与习题作业练习-第2章
- 疑问
- 习题
-
- 练习题2.1
- 练习题2.2
- 练习题2.3
- *练习题2.4
- 练习题2.5
- 练习题2.6
- *练习题2.7
- 练习题2.8
- *练习题2.9
- 练习题2.10
- 练习题2.11
- 练习题2.12
- 练习题2.13
- 练习题2.14
- 练习题2.15
- 练习题2.16
- 练习题2.17
- 练习题2.18
- 练习题2.19
- 练习题2.20
- 练习题2.21
- 练习题2.22
- 练习题2.23
- 练习题2.24
- 练习题2.25
- 练习题2.26
- 练习题2.27
- 练习题2.28
- 练习题2.29
- 练习题2.30
- 练习题2.31
- 练习题2.32
- 练习题2.33
- 练习题2.34
- *练习题2.35
- 练习题2.36
- 练习题2.37
- 练习题2.38
- ?练习题2.39
- 练习题2.40
- 练习题2.41
- 练习题2.42
- 练习题2.43
- 练习题2.44
- 练习题2.45
- 练习题2.46
- 练习题2.47
- 练习题2.48
- 练习题2.49
- 练习题2.50
- 练习题2.51
- 练习题2.52
- 练习题2.53
- 练习题2.54
- 整理
-
- 定义与公式
-
- 2.1 无符号数编码的定义
- 2.2 补码编码的定义
- 2.3 补码转换为无符号数
- 2.4 无符号数转换为补码
- 2.5 无符号数的零扩展
- 2.6 补码的符号扩展
- 2.7 截断无符号数
- 2.8 截断补码
- 2.9 无符号数加法
- 2.10 检测无符号数加法中的溢出
- 2.11 无符号数求反
- 2.12 补码加法
- 2.13 检测补码加法中的溢出
- 2.14 补码的非
- 2.15 无符号乘法
- 2.16 补码乘法
- 2.17 无符号和补码乘法的位级等价性
- 2.18 乘以2的幂
- 2.19 与2的幂相乘的无符号乘法
- 2.20 与2的幂相乘的补码乘法
- 2.21 除以2的幂的无符号除法
- 2.22 除以2的幂的补码除法,向下舍入
- 2.23 除以2的幂的补码除法,向上舍入
- 2.24 IEEE754标准表示浮点数
疑问
疑问一 练习题2.41解答中 m = 0 m=0 m=0的问题(已解决)
问题:练习题2.41解答将情况分为 m > 0 m>0 m>0和 m = 0 m=0 m=0两种情况,在证明 m > 0 m>0 m>0的情况后指出 m = 0 m=0 m=0时形式A和B都会少一次移位。为什么需要考虑m=0的情况?
回答:当 m = 0 m=0 m=0时x<<m
即x本身,不需要计算左移0位的结果。
习题
练习题2.1
A. 0011 1001 1010 0111 1111 1000
B. 0XC97B
C. 1101 0101 1110 0100 1100
D. 0X26E7B5
练习题2.2
n n n | 2 n 2^n 2n(十进制) | 2 n 2^n 2n(十六进制) |
---|---|---|
9 | 512 | 0x200 |
19 | 524288 | 0x80000 |
14 | 16384 | 0x4000 |
16 | 65536 | 0x10000 |
17 | 131072 | 0x20000 |
5 | 32 | 0x20 |
7 | 128 | 0x80 |
练习题2.3
十进制 | 二进制 | 十六进制 |
---|---|---|
0 | 0000 0000 | 0x00 |
167 | 1010 0111 | 0xA7 |
62 | 0011 1110 | 0x3E |
188 | 1011 1100 | 0xBC |
55 | 0011 0111 | 0x37 |
136 | 1000 1000 | 0x88 |
243 | 1111 0011 | 0xF3 |
82 | 0101 0010 | 0x52 |
172 | 1010 1100 | 0xAC |
231 | 1110 0111 | 0xE7 |
*练习题2.4
A. 0x503c+0x0008=0x5044
B. 0x503c-0x0040=0x4f5c
C. 0x503c+0x0004=0x5040
D. 0X50ea-0x503c=0x00ae
更正:
对于B来说:0x503c-0x0040=0x4ffc,第3位应该是3+16-4,这里错误计算成了3+10-4
对于C来说: 0x503c+64=0x503c+0x0040=0x507c ,64的16进制计算错误
练习题2.5
A. 小端法:21 大端法:87
B. 小端法:21 43 大端法:87 65
C. 小端法:21 43 65 大端法:87 65 43
练习题2.6
A.整数:0000 0000 0011 0101 1001 0001 0100 0001 浮点数: 0100 1010 0101 0110 0100 0101 0000 0100
B.21
C.整数前面一部分不匹配,浮点数只在中间的部分匹配。
*练习题2.7
61 62 63 64 65 66
strlen函数不计算null字符
练习题2.8
运算 | 结果 |
---|---|
a a a | [01101001] |
b b b | [01010101] |
∼ a \sim a ∼a | [10010110] |
∼ b \sim b ∼b | [10101010] |
a & b a\&b a&b | [01000001] |
a ∣ b a\mid b a∣b | [01111101] |
a ∧ b a^\land b a∧b | [00111100] |
*练习题2.9
A.
黑色RGB位向量[0 0 0],位向量的补是[1 1 1],对应白色,所以黑色的补是白色
蓝色RGB位向量[0 0 1],位向量的补是[1 1 0],对应黄色,所以蓝色的补是黄色
绿色RGB位向量[0 1 0],位向量的补是[1 0 1],对应红紫色,所以绿色的补是红紫色
蓝绿色RGB位向量[0 1 1],位向量的补是[1 0 0],对应红色,所以蓝绿色的补是红色
因为位向量 ∼ ( ∼ a ) = a \sim(\sim a)=a ∼(∼a)=a,所以可得:
白色的补是黑色
黄色的补是蓝色
红紫色的补是绿色
红色的补是蓝绿色
B.
蓝色|绿色 =[0 0 1] | [0 1 0]=[0 1 1] =蓝绿色
黄色&蓝绿色=[1 1 0] & [0 1 1]=[1 1 1]=白色
红色^红紫色=[1 0 0] ^ [1 0 1]=[0 0 1]=蓝色
更正:
B中 黄色&蓝绿色=[1 1 0] & [0 1 1]=[0 1 0]=绿色 这里位运算结果错了。
练习题2.10
步骤 | *x | *y |
---|---|---|
初始 | a | b |
第1步 | a | a^b |
第2步 | a ^ (a^b)=b | a^b |
第3步 | b | (a^b) ^ b=a |
练习题2.11
A.first=last=k
B.当inplace_swap(k,k)
时会导致
*k = *k ^ *k //*k此时为0
*k = *k ^ *k
*k = *k ^ *k //*k执行第一行后一直为0
C.把for循环的结束条件中的等号去掉
练习题2.12
A.x=x&0xFF
B.x=(~x&0x00)&(x&0xFF)
C.x=x|0xFF
更正:
B 可以为 x=x^~0xFF
练习题2.13
int bool_or(int x, int y) {
int result = bis(x,y);
return result;
}
int bool_xor(int x, int y) {
int result = bis(bic(x,y),bic(y,x));
return result;
}
练习题2.14
x=0110 0110
y=0011 1001
表达式 | 值 | 表达式 | 值 |
---|---|---|---|
x & y | 0x20 | x && y | 0x01 |
x | y | 0x7F | x || y | 0x01 |
~x | ~y | 0xDF | !x || !y | 0x00 |
x & !y | 0x00 | x && ~y | 0x01 |
练习题2.15
!(x^y)
练习题2.16
x | x<<3 | x>>2(逻辑的) | x>>2(算术的) | ||||
---|---|---|---|---|---|---|---|
十六进制 | 二进制 | 二进制 | 十六进制 | 二进制 | 十六进制 | 二进制 | 十六进制 |
0xc3 | 1100 0011 | 0001 1000 | 0x18 | 0011 0000 | 0x30 | 1111 0000 | 0xF0 |
0x75 | 0111 0101 | 1010 1000 | 0xA8 | 0001 1101 | 0x1D | 0001 1101 | 0x1D |
0x87 | 1000 0111 | 0011 1000 | 0x38 | 0010 0001 | 0x21 | 1110 0001 | 0xE1 |
0x66 | 0110 0110 | 0011 0000 | 0x30 | 0001 1001 | 0x19 | 0001 1001 | 0x19 |
练习题2.17
x ⃗ \vec{x} x | B 2 U 4 ( x ⃗ ) B2U_4(\vec{x}) B2U4(x) | B 2 T 4 ( x ⃗ ) B2T_4(\vec{x}) B2T4(x) | |
---|---|---|---|
十六进制 | 二进制 | ||
0xE | [1110] | 2 3 + 2 2 + 2 1 = 14 2^3+2^2+2^1=14 23+22+21=14 | − 2 3 + 2 2 + 2 1 = − 2 -2^3+2^2+2^1=-2 −23+22+21=−2 |
0x0 | [0000] | 0 0 0 | 0 0 0 |
0x5 | [0101] | 2 2 + 2 0 = 5 2^2+2^0=5 22+20=5 | 2 2 + 2 0 = 5 2^2+2^0=5 22+20=5 |
0x8 | [1000] | 2 3 = 8 2^3=8 23=8 | − 2 3 = − 8 -2^3=-8 −23=−8 |
0xD | [1101] | 2 3 + 2 2 + 2 0 = 13 2^3+2^2+2^0=13 23+22+20=13 | − 2 3 + 2 2 + 2 0 = − 3 -2^3+2^2+2^0=-3 −23+22+20=−3 |
0xF | [1111] | 2 3 + 2 2 + 2 1 + 2 0 = 15 2^3+2^2+2^1+2^0=15 23+22+21+20=15 | − 2 3 + 2 2 + 2 1 + 2 0 = − 1 -2^3+2^2+2^1+2^0=-1 −23+22+21+20=−1 |
练习题2.18
A.736
B.-88
C.40
D.-48
E.120
F.136
G.504
H.192
I.-72
练习题2.19
x x x | T 2 U 4 ( x ) T2U_4(x) T2U4(x) |
---|---|
-8 | [1000]=8 |
-3 | [1101]=13 |
-2 | [1110]=14 |
-1 | [1111]=15 |
0 | [0000]=0 |
5 | [0101]=5 |
练习题2.20
x x x | T 2 U 4 ( x ) T2U_4(x) T2U4(x) |
---|---|
-8 | T 2 U 4 ( − 8 ) = − 8 + 2 4 = 8 T2U_4(-8)=-8+2^4=8 T2U4(−8)=−8+24=8 |
-3 | T 2 U 4 ( − 3 ) = − 3 + 2 4 = 13 T2U_4(-3)=-3+2^4=13 T2U4(−3)=−3+24=13 |
-2 | T 2 U 4 ( − 2 ) = − 2 + 2 4 = 14 T2U_4(-2)=-2+2^4=14 T2U4(−2)=−2+24=14 |
-1 | T 2 U 4 ( − 1 ) = − 1 + 2 4 = 15 T2U_4(-1)=-1+2^4=15 T2U4(−1)=−1+24=15 |
0 | T 2 U 4 ( 0 ) = 0 T2U_4(0)=0 T2U4(0)=0 |
5 | T 2 U 4 ( 5 ) = 5 T2U_4(5)=5 T2U4(5)=5 |
练习题2.21
表达式 | 类型 | 求值 |
---|---|---|
-2147483647-1 == 2147483648U | 无符号 | 1 |
-2147483647-1 <2147483647 | 有符号 | 1 |
-2147483647-1U < 2147483647 | 无符号 | 0 |
-2147483647-1 <-2147483647 | 有符号 | 1 |
-2147483647-1U <-2147483647 | 无符号 | 1 |
练习题2.22
A. B 2 T 4 ( [ 1011 ] ) = − x 4 − 1 2 4 − 1 + ∑ n = 0 4 − 2 x i 2 i = − 2 3 + 2 1 + 2 0 = − 5 B2T_4([1011])=-x_{4-1}2^{4-1}+\displaystyle\sum_{n=0}^{4-2}x_i2^i=-2^3+2^1+2^0=-5 B2T4([1011])=−x4−124−1+n=0∑4−2xi2i=−23+21+20=−5
B. B 2 T 5 ( [ 11011 ] ) = − x 5 − 1 2 5 − 1 + ∑ n = 0 5 − 2 x i 2 i = − 2 4 + 2 3 + 2 1 + 2 0 = − 5 B2T_5([11011])=-x_{5-1}2^{5-1}+\displaystyle\sum_{n=0}^{5-2}x_i2^i=-2^4+2^3+2^1+2^0=-5 B2T5([11011])=−x5−125−1+n=0∑5−2xi2i=−24+23+21+20=−5
C. B 2 T 6 ( [ 111011 ] ) = − x 6 − 1 2 6 − 1 + ∑ n = 0 6 − 2 x i 2 i = − 2 5 + 2 4 + 2 3 + 2 1 + 2 0 = − 5 B2T_6([111011])=-x_{6-1}2^{6-1}+\displaystyle\sum_{n=0}^{6-2}x_i2^i=-2^5+2^4+2^3+2^1+2^0=-5 B2T6([111011])=−x6−126−1+n=0∑6−2xi2i=−25+24+23+21+20=−5
练习题2.23
A.
w | fun1(w) | fun2(w) |
---|---|---|
0x00000076 | 0x76 | 0x76 |
0x87654321 | 0x21 | 0x21 |
0x000000C9 | 0xC9 | 0xFFFFFFC9 |
0xEDCBA987 | 0x87 | 0xFFFFFF87 |
B.fun1从无符号数的最低有效位取1字节,高位皆置为0,然后转化为补码
fun2从无符号数的最低有效位取1字节,高位用根据第8位置为1或0,然后转化为补码
练习题2.24
十六进制 | 无符号 | 补码 | |||
---|---|---|---|---|---|
原始值 | 截断值 | 原始值 | 截断值 | 原始值 | 截断值 |
0 | 0 | 0 | 0 | 0 | 0 |
2 | 2 | 2 | 2 | 2 | 2 |
9 | 1 | 9 | 1 | -7 | 1 |
B | 3 | 11 | 3 | -5 | 3 |
F | 7 | 15 | 7 | -1 | -1 |
练习题2.25
因为无符号数length=0时length-1的结果为 U M a x 32 UMax_{32} UMax32,第一次循环的比较条件变为了无符号数0<= U M a x 32 UMax_{32} UMax32,所以程序会访问一个长度为0数组的0号元素,导致出错。
练习题2.26
A.当字符串s比字符串t短时还结果会不正确
B.因为strlen函数返回无符号整数,当字符串s短于字符串t时,无符号整数相减仍大于0,导致函数会返回1。
C.将return strlen(s) - strlen(t) > 0;
改为return (int)(strlen(s) - strlen(t)) > 0;
更正:
C可以为return strlen(s)>strlen(t)
练习题2.27
int uadd_ok(unsigned x,unsigned y){
return x+y>=x;
}
练习题2.28
x | − 4 u x -_4^ux −4ux | ||
---|---|---|---|
十六进制 | 十进制 | 十进制 | 十六进制 |
0 | 0 | 0 | 0 |
5 | 5 | 11 | B |
8 | 8 | 8 | 8 |
D | 13 | 3 | 3 |
F | 15 | 1 | 1 |
练习题2.29
x | y | x+y | x + 5 t y x+_5^ty x+5ty | 情况 |
---|---|---|---|---|
[10100] | [10001] | [100101] | [00101] | 负溢出 |
[11000] | [11000] | [110000] | [10000] | 正常 |
[10111] | [01000] | [11111] | [11111] | 正常 |
[00010] | [00101] | [00111] | [00111] | 正常 |
[01100] | [00100] | [010000] | [10000] | 正溢出 |
练习题2.30
/* Determine whether arguments can be added without overflow */
int tadd_ok(int x,int y){
int sum = x+y;
int neg_over = x < 0 && y < 0 && sum >= 0;
int pos_over = x >= 0 && y >= 0 && sum < 0;
return !neg_over && !pos_over;
}
练习题2.31
当发生正溢出时, s u m = x + y − 2 32 sum=x+y-2^{32} sum=x+y−232 。而 s u m − x = y − 2 32 sum-x=y-2^{32} sum−x=y−232。因为 y < 2 31 y<2^{31} y<231,所以 y − 2 32 < − 2 31 y-2^{32}<-2^{31} y−232<−231,即 s u m − x < − 2 31 sum-x<-2^{31} sum−x<−231。所以 s u m − x = s u m − x + 2 32 = y − 2 32 + 2 32 = y sum-x=sum-x+2^{32}=y-2^{32}+2^{32}=y sum−x=sum−x+232=y−232+232=y,同理 s u m − y = x sum-y=x sum−y=x。所以即使发生正溢出,该段代码也会返回真值。发生负溢出时也同理,所以本题代码无法生效。
练习题2.32
当 y = − 2 31 y=-2^{31} y=−231时, − y = 2 31 -y=2^{31} −y=231,发生正溢出 − y = 2 31 − 2 32 = − 2 31 -y=2^{31}-2^{32}=-2^{31} −y=231−232=−231,tadd_ok(x,-y)
会在 x < 0 x<0 x<0判断为溢出,从而导致tsub_ok(x,y)
判断为溢出,而事实上当 x < 0 , y = − 2 31 x<0,y=-2^{31} x