《深入理解计算机系统》第四周学习笔记

一、知识点总结

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

二、遇到的问题

对于无符号数的截断和补码数字的截断过程、原理不甚清楚

三、学习感想总结

本周对于《信息的表示和处理》这一章节的学习有些吃力,阅读书上的定义解释有些晦涩难懂,进制转换、求补码、逻辑右移之类的还有些基础知识,其余的很多内容如截断、有符号数和无符号数之间的转换都是知其然不知其所以然,做练习题时都要看着教材上的公式才能做出来,而且看不太懂许多公式的推理过程和原理,希望老师能在下节课上讲解一下具体应用。

时间: 2024-11-07 05:07:26

《深入理解计算机系统》第四周学习笔记的相关文章

深入理解计算机系统9个重点笔记

引言 深入理解计算机系统,对我来说是部大块头.说实话,我没有从头到尾完完整整的全部看完,而是选择性的看了一些我自认为重要的或感兴趣的章节,也从中获益良多,看清楚了计算机系统的一些本质东西或原理性的内容,这对每个想要深入学习编程的程序员来说都是至关重要的.只有很好的理解了系统到底是如何运行我们代码的,我们才能针对系统的特点写出高质量.高效率的代码来.这本书我以后还需要多研究几遍,今天就先总结下书中我已学到的几点知识. 重点笔记 编写高效的程序需要下面几类活动: 选择一组合适的算法和数据结构.这是很

第十四周学习笔记

虚拟存储器 虚拟存储器是硬件异常.硬件地址翻译.主存.磁盘文件和内核软件的完美交互. 虚拟存储器的特点: 中心的 强大的 危险的 物理和虚拟寻址 计算机系统的主存被组织成一个由M个连续的字节大小的单元组成的数据 每个字节都有一个唯一的物理地址 第一个字节的地址为0,接下来的抵制依次+1 这种方式称为物理寻址 虚拟寻址时,CPU通过生成一个虚拟地址来访问主存,该地址被送到存储器之前先转换成适当的物理地址.该任务叫做地址翻译. 地址需要CPU硬件和操作系统之间紧密合作 存储器管理单元(在CPU上)利

Python第四周 学习笔记(1)

函数 Python的函数没有return语句,隐式会返回一个None值 函数是可调用的对象,callable() 函数参数 参数调用时传入的参数要和定义的个数相匹配(可变参数例外) 位置参数 def f(x, y, z) 调用使用 f(1, 3, 5) 按照参数定义顺序传入实参 关键字参数 def f(x, y, z) 调用使用 f(x=1, y=3, z=5) 使用形参的名字来出入实参的方式,如果使用了形参名字,那么传参顺序就可和定义顺序不同 传参 要求位置参数必须在关键字参数之前传入,位置参

《深入理解java虚拟机》学习笔记四/垃圾收集器GC学习/一

Grabage Collection      GC GC要完成的三件事情: 哪些内存需要回收? 什么时候回收? 如何回收? 内存运行时区域的各个部分中: 程序计数器.虚拟机栈.本地方法栈这3个区域随线程而生,随线程而灭. 栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和入栈的操作. 每一个栈帧中分配多少内存基本上是在类结构确定下来时就已知的,因此, 这几个区域的内存分配和回收都具备确定性,在这几个区域内就不需过多考虑回收的问题. 因为方法结束或者线程结束时,内存自然就跟着回收了. 而ja

《深入理解C指针》学习笔记(1)--- 指针之外

C语言从诞生之初就非常善于和硬件打交道,经过这么多年的发展之后,其灵活性和超强的特征是受到几乎所有程序员的肯定.C语言的这种灵活性很大一部分程度来源与C指针,指针为C语言动态操控内存提供了支持,同时也便于访问硬件.由于编程的本质就是操控数据,而数据大多都在内存中,理解C管理内存的工作原理,就显得尤为重要了.知道malloc()函数能够从堆上申请内存,理解内存分配的本质则是另外的事. 请看代码例子: 1 #include <stdio.h> 2 #include <stdlib.h>

(转)《深入理解java虚拟机》学习笔记5——Java Class类文件结构

Java语言从诞生之时就宣称一次编写,到处运行的跨平台特性,其实现原理是源码文件并没有直接编译成机器指令,而是编译成Java虚拟机可以识别和运行的字节码文件(Class类文件,*.class),字节码文件是一种平台无关的中间编译结果,字节码文件由java虚拟机读取,解析和执行,java虚拟机屏蔽了不同操作系统和硬件平台的差异性. 如今的java虚拟机已经称为一种通用平台,不但能够运行java语言,Groovy,JRuby,Jython等一大批动态语言也可以直接在Java虚拟机上运行,其原理也是这

第四周学习笔记

前周和本周主要学习登录和注册的内容,其中登录和注册分别有三种方法.登录可以通过查询标量.参数.参数方向三种命令来实现:注册有写入.异常.存储过程三种实现命令. 结合上课内容,我们分别总结和实现这几种命令. (1)实现登录: ①运用查询标量: C#主要代码如下: private void btn_LogIn_Click(object sender, EventArgs e) { SqlConnection sqlC = new SqlConnection(); sqlC.ConnectionStr

Java内存区域--《深入理解Java虚拟机》学习笔记(一)

程序计数器 程序计数器干嘛的? 有了它,字节码解释器才可以知道下一条要执行的字节码指令是哪个. 无论是取下一条指令还是分支.循环.跳转.中断.线程恢复,都需要这个程序计数器. 程序计数器存在哪? 虚拟机区别于硬件,组成原理里学的程序计数器是用CS和IP寄存器来存,来表示指令地址. 而Java把程序计数器存在内存里. 我好像在操作系统中也听说过程序计数器? 是跟操作系统中的程序计数器有点类似. 在一个时刻,一个处理器只会执行一条线程,HotSpot中使用原生线程模型,OS线程和Java线程1:1映

深入理解 Java 虚拟机之学习笔记(2)

本节介绍 Java堆的OutOfMemoryError测试 Eclipse Memory Analyzer分析内存溢出 虚拟机栈和本地方法栈StackOverflowError测试 方法区和运行时常量池溢出 本机直接内存溢出 一.Java堆的OutOfMemoryError测试 (1)首先设置debug configuration.如下图所示: (2)接下来进行编码操作,如下面的代码所示,不断添加新的对象到List中.由于Java堆设置的大小为20M并且不可扩展(将堆的最小值-Xms参数与最大值