一、知识点总结
1.信息存储
练习题2.4
0x503c+0x8=0x5044
0x503c-0x40=0x4ffc
0x503c+64=0x503c+0x40=0x507c
0x50ea-0x503c=0xae
1)字长:指明整数和指针数据的标称大小。一个字长为w的机器的虚拟地址范围为0~2^(w-1),程序最多访问2^w个字节
int 、char 4字节,单精度float 字节,双精度double 8字节
2)小端法:最低有效字节在最前面的顺序存储
大端法:最高有效字节在最前面的顺序存储
练习题2.6
0x00359141=00000000001101011001000101000001
0x4a564504= 01001010010101100100010100000100
有21个匹配位的序列
除了最高有效位1,整数的所有位都嵌在浮点数中。浮点数有一些非零的高位不与整数中的高位相配。
3)C语言中字符串被编码为一个以null(值为0)字符结尾的字符数组。在使用ASCII码作为字符码的任何系统上都会得到相同的结果,与字节顺序和字大小规则无关
练习题2.7
打印61 62 63 64 65 66,strlen不计算终止的空字符,所以只打印到字符f
练习题2.8
a=01101001 b=01010101 ~a=10010110 ~b=10101010
a&b=01000001 a|b=01111101 a^b=00111100
练习题2.11
A.first和last的值都为k,所以想交换正中间的元素和自己
B.Inplace_swap的参数x和y都指向同一位置,*x^*y=0,然后将0作为数组正中元素,,且后面都把该元素设为0
C.将reverse_array第四行测试替换为first<last,因为没必要交换正中间的元素和自己
4)逻辑运算符 | | && !,与位运算符相区别,逻辑运算认为所有非零的参数都表示true,参数0表示false。如果对第一个参数求值就能确定表达式的结果,那么逻辑运算符就不会对第二个参数求值
练习题2.13
int result = bis(x,y);
int result = bis(bic(x,y),bic(y,x));
bs运算等价于or,bic(x,m)等价于x&~m
x^y = (x&~y) | (~x&y)
练习题2.14
x&y=0x20 x|y=0x7f ~x|~y=0xdf x&!y=0x00
x&&y=0x01 x||y=0x01 !x||!y=0x00 x&&~y=0x01
练习题2.18
A 440
B 20
C -424
D -396
E 69
F -313
G 16
H 12
I -276
J 32
练习题2.19
X(十六进制) |
X |
T2U4(x) |
0x8 |
-8 |
8 |
0xD |
-3 |
13 |
0xE |
-2 |
14 |
0xF |
-1 |
15 |
0x0 |
0 |
0 |
0x5 |
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.23
w |
Fun1(w) |
Fun2(w) |
0x00000076 |
0x00000076 |
0x00000076 |
0x87654321 |
0x00000021 |
0x00000021 |
0x000000C9 |
0x000000C9 |
0xFFFFFFC9 |
0xEDCBA987 |
0x00000087 |
0xFFFFFF87 |
练习题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-1将进行无符号运算,等价于模数加法,结果得到UMax。因为任何数都是小于等于UMax的,所以<=比较永真,代码将访问数组a的非法元素。
改正:1.将length声明为int类型 2.将for循环测试条件改为i>length
练习题2.27
函数是对确定无符号加法是否溢出的规则的直接实现
练习题2.29
x |
y |
x+y |
x+t5y |
情况 |
-12[10100] |
-15[10001] |
-27[100101] |
5[00101] |
1 |
-8[11000] |
-8[11000] |
-16[110000] |
-16[110000] |
2 |
-9[10111] |
8[01000] |
-1[111111] |
-1[11111] |
2 |
2[00010] |
5[00101] |
7[000111] |
7[00111] |
3 |
12[01100] |
4[00100] |
16[010000] |
-16[10000] |
4 |
练习题2.33
W=4,TMin4=-8,因此-8是它自己的逆元,其他数值是通过整数非来取非的
x |
-t4x |
||
十六进制 |
十进制 |
十进制 |
十六进制 |
0 |
0 |
0 |
0 |
5 |
5 |
-5 |
B |
8 |
-8 |
-8 |
8 |
D |
-3 |
3 |
3 |
F |
-1 |
1 |
1 |
对于无符号数的非,位的模式是相同的
练习题2.34
模式 |
x |
y |
x*y |
截断了的x*y |
无符号数 补码 |
4[100] |
5[101] |
20[010100] |
4[100] |
-4[100] |
-3[101] |
12[001100] |
-4[100] |
|
无符号数 补码 |
2[010] |
7[111] |
14[001110] |
6[110] |
2[010] |
-1[111] |
-2[111110] |
-2[110] |
|
无符号数 补码 |
6[110] |
6[110] |
36[100100] |
4[100] |
-2[110] |
-2[110] |
4[000100] |
-4[100] |
5)x>>k将x算数右移k个位置,x>>>k会对x做逻辑右移
逻辑右移是在左端补k个0,算数右移是在左端补k个最高有效位的值
6)无符号运算可视为一种模运算,无符号加法等价于计算和模上2^w,可以通过简单的丢弃x+y的w+1位表示的最高位来计算这个数值
练习题2.39
表达式变成了-(x<<m)。设字长为w,n=w-1。形式B要计算(x<<w)-(x<<m),但是将x向左移动w位会得出0
练习题2.40
K |
移位 |
加法/减法 |
表达式 |
6 |
2 |
1 |
(x<<2)+(x<<1) |
31 |
1 |
1 |
(x<<5)-x |
-6 |
2 |
1 |
(x<<1)-(x<<3) |
55 |
2 |
2 |
(x<<6)-(x<<3)-x |
练习题2.42
int div16(int x){
int bias = (x>>31) & 0xF;
return (x+bias)>>4;
}
表达式x>>产生一个字,如果x是负数,这个字为全1,否则为全0。通过掩码屏蔽适当的位则得到期望的偏置值。
练习题2.43
M=31,是用(x<<5)-x来计算x*M
N=8,当y是负数时,加上偏移量7并右移3位
6)同样字长的有符号数和无符号数转换:数值可能改变,位模式不变。生成一个数的无符号表示和x的补码表示相同
练习题2.44
A .(x>0) | | ((x-1)<0)
假。设x等于-2 147 483 648(TMin32),那么有x-1等于2 147 483 647(TMax32)
B .(x&7) !=7 | | (x<<29<0)
真。如果(x&7) !=7这个表达式值为0,那么必须有位x2等于1。当左移29位时,这个位将变成符号位
C .(x*x)>=0
假。当x为65 535(0xFFFF)时,x*x为-131 071(0xFFFE0001)
D .x<0 | | -x<=0
真。如果x是非负数,则-x是非正的
E .x>0 | | -x>0
假。设x等于-2 147 483 648(TMin32),则x和-x都是负数
F .x+y==uy+ux
真。补码和无符号加法有相同的位级行为,而且是可交换的
G .x*~y+uy*ux==-x
真。~y等于-y-1,uy*ux等于x*y,因此等式左边等价于x*-y-x+x*y
练习题2.45
小数值 |
二进制表示 |
十进制表示 |
1/8 |
0.001 |
0.125 |
3/4 |
0.11 |
0.75 |
25/16 |
1.1001 |
1.5625 |
43/16 |
10.1011 |
2.6875 |
9/8 |
1.001 |
1.125 |
47/8 |
101.111 |
5.875 |
51/16 |
11.0011 |
3.1875 |
将一个数表示为形如x/2^k的小数,使用x的二进制表示,并把二进制小数点插入右边算起的第k个位置
练习题2.47
位 |
e |
E |
2^E |
f |
M |
2^E*M |
V |
十进制 |
00000 |
0 |
0 |
1 |
0/4 |
0/4 |
0/4 |
0 |
0.0 |
00001 |
0 |
0 |
1 |
1/4 |
1/4 |
1/4 |
1/4 |
0.25 |
00010 |
0 |
0 |
1 |
2/4 |
2/4 |
2/4 |
1/2 |
0.5 |
00011 |
0 |
0 |
1 |
3/4 |
3/4 |
3/4 |
3/4 |
0.75 |
00100 |
1 |
0 |
1 |
0/4 |
4/4 |
4/4 |
1 |
1.0 |
00101 |
1 |
0 |
1 |
1/4 |
5/4 |
5/4 |
5/4 |
1.25 |
00110 |
1 |
0 |
1 |
2/4 |
6/4 |
6/4 |
3/2 |
1.5 |
00111 |
1 |
0 |
1 |
3/4 |
7/4 |
7/4 |
7/4 |
1.75 |
01000 |
2 |
1 |
2 |
0/4 |
4/4 |
8/4 |
2 |
2.0 |
01001 |
2 |
1 |
2 |
1/4 |
5/4 |
10/4 |
5/2 |
2.5 |
01010 |
2 |
1 |
2 |
2/4 |
6/4 |
12/4 |
3 |
3.0 |
01011 |
2 |
1 |
2 |
3/4 |
7/4 |
14/4 |
7/2 |
3.5 |
01100 |
- |
- |
- |
- |
- |
- |
无穷 |
- |
01101 |
- |
- |
- |
- |
- |
- |
NaN |
- |
01110 |
- |
- |
- |
- |
- |
- |
NaN |
- |
01111 |
- |
- |
- |
- |
- |
- |
NaN |
- |
7)零扩展:将无符号数转换为一个更大的数据类型,在表示的开头添加0
8)符号扩展:将一个补码数字转换成一个更大的数据类型,在表示中添加最高有效位的值的副本
练习题2.50
原始值 |
舍入后的值 |
||
10.010 |
2(1/4) |
10.0 |
2 |
10.011 |
2(3/8) |
10.1 |
2(1/2) |
10.110 |
2(3/4) |
11.0 |
3 |
11.001 |
3(1/8) |
11.0 |
3 |
练习题2.52
格式A |
格式B |
注 |
||
位值 |
位值 |
|||
011 0000 |
1 |
0111 000 |
1 |
|
101 1110 |
15/2 |
1001 111 |
15/2 |
|
010 1001 |
25/32 |
0110 100 |
3/4 |
向下舍入 |
110 1111 |
31/2 |
1011 000 |
16 |
向上舍入 |
000 0001 |
1/64 |
0001 000 |
1/64 |
Denorm->norm |
9)补码范围不对称:|TMin|=|TMax|+1
10)最大的无符号数值比补码的最大值的两倍多1
练习题2.54
A .x==(int)(double)x
真,因为double类型比int类型有更大的精度和范围
B .x==(int)(float)x
假,例如当x为TMax时
C .d==(double)(float)d
假,例如当d为le40时,右边得到正无穷
D .f==(float)(double)f
真,因为double类型比float类型具有更大的精度和范围
E .f == -(-f)
真,因为浮点数取非就是对它的符号位取反
F .1.0/2==1/2.0
真,在执行除法之前,分子和分母都会被转换成浮点表示
G .d*d>=0.0
真,虽然它可能会溢出到正无穷
H .(f+d)-f == d
假,例如当f是1.0e20而d是1..0时,表达式f+d会舍入到1.0e20,因此左边的表达式求值得到0.0,而右边是1.0
二、遇到的问题
对于无符号数的截断和补码数字的截断过程、原理不甚清楚
三、学习感想总结
本周对于《信息的表示和处理》这一章节的学习有些吃力,阅读书上的定义解释有些晦涩难懂,进制转换、求补码、逻辑右移之类的还有些基础知识,其余的很多内容如截断、有符号数和无符号数之间的转换都是知其然不知其所以然,做练习题时都要看着教材上的公式才能做出来,而且看不太懂许多公式的推理过程和原理,希望老师能在下节课上讲解一下具体应用。