CSAPP(深入理解计算机系统)第二版家庭作业答案-第二章

答案均由本人完成,并且实验或者调试,欢迎参考!


2.55-2.57
略


2.58
int is_little_endian(){
int i=1;
return *((char*)&i);
}


2.59
int test_2_59(int x,int y){
return (x&0xff)|(y&(~0xff));
}


2.60
unsigned replace_byte(unsigned x,unsigned char b,int i){
    unsigned int mask=0xff;
    unsigned int val=b;
    unsigned int shift_val=i<<3;
    mask=mask<<shift_val;
    val=val<<shift_val;
    return (x&~mask)|val;
}


2.61
A.
!~x;
B.
!x;
C.
!~(x>>24)
D.
!(x&0xff)


2.62
bool int_shifts_are_logical(){
int x=-1;
x=x>>(sizeof(int)<<3-1);
return !~x; 
}


2.63
int sra(int x,int k){
    int xsrl=(unsigned)x>>k;
    int w=sizeof(int)<<3;
    //if(x<0)
    //    return xsrl|~((1<<(w-k-1))-1);
    //return xsrl;
//不用逻辑运算符
int z=1<<(w-k-1);
return xsrl|~((z&xsrl)-1);
}




unsigned srl(unsigned x,int k){
    unsigned xsra=(int)x>>k;
    int w=sizeof(int)<<3;
    return xsra&((1<<(w-k))-1);
}


2.64
//求任意偶数位是否为1,从0开始计算
int any_even_one(unsigned x){
while(x){
if(x&1)
return 1;
x=x>>2;
}
return 0;
}


2.65
//求是否包含偶数个1
int even_ones(unsigned x){
int w=32;
while(w>1){
w=w>>1;
x=(x>>w)^x;
}
return !(x&1);
}


2.66
//求最高有效位的1
int leftmost_one(unsigned x){
    x |= (x >> 1);
    x |= (x >> 2);
    x |= (x >> 4);
    x |= (x >> 8);
    x |= (x >> 16);  //这里一定会得到从最高位的1到最低位的全部为1
    return x^(x>>1);
}


2.67
A.在int为32位的机器上不应该左移32位
B.
int bad_int_size_is_32(){
int set_msb=1<<31;
return set_msb && set_msb<0;
}
C.
int bad_int_size_is_32(){
int z=1<<15;
z=z<<15;
int set_msb=z<<1;
int beyond_msb=z<<2;
return set_msb && !beyond_msb;
}

2.68
int lower_bits(int x,int n){
return x&((2<<(n-1))-1);
}


2.69
unsigned rotate_right(unsigned x,int n){
int w=sizeof(unsigned)<<3;
return x>>n | x<<(w-n-1)<<1;
}


2.70
int fits_bits(int x,int n){
x=x>>(n-1); //x全为1或者全为0能表示 
return !(x && ~x);
}


2.71
A.
word是unsigned类型所以会进行无符号扩展,比如原字节是0xff(-1),这个函数将返回0xff(255),而非题目要求
B.
int xbyte(packed_t word,int bytenum){
return ((int)(word<<((3-bytenum)<<3)))>>24;
}




2.72
A.size_t是unsigned类型,相减结果会提升至unsigned,而unsigned类型总是>=0
B.
void copy_int(int val,void *buf,unsigned maxbytes){
if(maxbytes>=sizeof(val))
memcpy(buf,(void*)&val,sizeof(val));
}


2.73
int saturating_add(int x,int y){
int sum=x+y;
if( x>=0 && y>=0 && sum<0)
return INT_MAX;
if(x<0 && y<0 && sum>=0)
return INT_MIN;
return sum;
}


2.74
int tsub_ovf(int x,int y){
int sub=x-y;
if(x >=0 && y<0 && sub<0)
return 1;
if( x<0 && y>=0 && sub>=0)
return 1;
return 0;
}


2.75
unsigned unsigned_high_prod(unsigned x,unsigned y)  
{  
    int w = sizeof(unsigned) << 3;  
int sx=(int)x;
int sy=(int)y;
int t= signed_high_prod(sx,sy);
return t+ ((sx>>(w-1))&1)*sy+((sy>>(w-1))&1)*sx;  
}


2.76
A.
(x<<2)+x
B.
(x<<3)+x
C.
(x<<5)-(x<<1)
D.
(x<<3)-(x<<6)


2.77
int divide_power2(int x,int k){
int bias= (x>>31) & ((1<<k)-1);
return (x+bias)>>k;
}


2.78
int mul5div8(int x){
int x=(x<<2)+x;
int bias= (x>>31) & 7;
return (x+bias)>>3;
}


2.79
int fiveeighths(int x){
int bias= (x>>31) & 7;
x=(x+bias)>>3;
return (x<<2)+x;
}


2.80
A.
~((1<<n)-1)
B.
((1<<n)-1)<<m


2.81
A.
x=0,y=Tmin
B.
总为1,位级表示相同
C.
~x=-x-1
~y=-y-1
~(x+y)=-x-y-1
-x-1-y-1!=-x-y-1
总为0
D.
总为1,无符号和有符号减法位级表示相同,而且最后都转成int类型,结果一致
E.
总为1,右移再左移必有1位丢失或者不丢失,丢失的这1位权值为正,值会变小


2.82
A.
等比数列求和a1*(1-q^n)/(1-q)
a1=Y/(2^k) q=1/(2^k)
假设n非常大,1-q^n可看作1
a1/(1-q)
所以通项公式是Y/(2^k-1)
B.
y=001 1/7
y=1001 3/5
y=000111 1/9

2.83
return sx==sy?(ux==uy)||((ux>uy)^sx):((ux<<1)==0 && (uy<<1)==0)||sx<sy;
或者
return ((ux<<1)==0 && (uy<<1)==0) || 
(!sx && sy) || 
(!sx && !sy && ux >= uy) ||
(sx && sy && ux <= uy);


2.84
A.
E M fV
2 1.01 0.01 5
e=1+2^(k-1)
f=01000..00
B.
E M fV
n 1.111.. 0.11.. 2^(n+1)-1
e=n+2^(k-1)-1
f=11111..11
C.
E M fV
2^(k-1)-2 1 0 2^(2^(k-1)-2)
e=2^k-3
f=0




2.85
最小的正非规格化数:2^(-2^14+2)*1/2^63
最小的正规格化数:2^(-2^14+2)
最大的规格化数:2^(2^14-1)*(2-1/2^63)




2.86
描述 Hex M E V
-0 0x8000 0 -62 --
最小的值>1 0x3f01 257/256 0 257*2^(-8)
256 0x4700 1 8 --
最大的非规格化数 0x00ff255/256 -62255*2^(-70)
负无穷 0xff00 -- -- --
0x3AA0 -- 13/8 -5 13*2^(-8)


2.87
格式A 格式B
位 值 位值
1 01110 001 -9/161 0110 0010 -9/16
0 10110 101 208 0 1110 1010208
1 00111 110 -7/10241 0000 0111     -7/1024
0 00000 101 3/(2^17)0 0000 0001 1/(2^10)
1 11011 000 -2^12 1 1111 0000负无穷
0 11000 100 3*2^80 1111 0000 正无穷
       


2.88
A.0
x转float有精度丢失,x=2^24+1=16777217
B.0
x=Tmax,y=Tmax,x+y溢出得到负数,而dx+dy不溢出
C.1
double可精确表示2^53内的所有整数,而相加不可能超出这个范围
D.0
32位乘法可能导致结果超出2^53,会导致舍入
E.0
dx或dy为0




2.89
float fpwr2(int x){
unsigned exp,frac;
unsigned u;
if(x<-149){
exp=0;
frac=0;
}
else if(x<-126){
exp=0;
frac= 1<<(149+x);
}
else if(x<128){
exp=x+127;
frac=0;
}
else{
exp=255;
frac=0;
}
u=exp<<23|frac;
return u2f(u);
}


2.90
0x40490fdb
0100 0000 0100 1001 0000 1111 1101 1011
A.
11.0010010000111111011011
B.
11.001001001001001001001001..
C.
从低9位,即2^(-9)


2.91
float_bits float_absval(float_bits f){
unsigned exp=f>>23&0xff;
unsigned frac=f&0x7fffff;
if(exp==0xff && frac!=0)
return f;
return f&0x7fffffff;
}


2.92
float_bits float_negate(float_bits f){
unsigned exp=f>>23&0xff;
unsigned frac=f&0x7fffff;
if(exp==0xff && frac!=0)
return f;
return f^0x80000000;
}


2.93
float_bits float_half(float_bits f){
unsigned sign=f>>31;
unsigned exp=f>>23&0xff;
unsigned frac=f&0x7fffff;
if(exp==0xff && frac!=0)
return f;
if(exp==0xff && frac==0)
return f;       //正无穷或者负无穷
if(exp ==0 || exp==1)
{
if(exp==1)
frac=frac|0x800000;
if((frac & 3)==3)
frac=(frac+1)>>1;
else
frac=frac>>1;
}
if(exp>0) {
exp-=1;
}
return (sign<<31) | (exp<<23) | frac;
}


2.94
float_bits float_twice(float_bits f){
unsigned sign=f>>31;
unsigned exp=f>>23&0xff;
unsigned frac=f&0x7fffff;
if(exp==0xff && frac!=0)
return f;
if(exp==0xff && frac==0)
return f;       //正无穷或者负无穷
if(exp ==0)
{ 
frac=frac<<1;
}
else{
exp+=1;
if(exp==0xff)
frac=0;
}
return (sign<<31) | (exp<<23) | frac;
}


2.95
float_bits float_i2f(int i){
if(i==0)
return 0;
unsigned sign=0;
unsigned frac=i;
if(i&0x80000000){
sign=1;
frac=~frac+1;
}
unsigned c=0;
while (!(frac&0x80000000))
{
frac=frac<<1;
++c;
}
unsigned exp= (31-c)+127;
frac=frac<<1;
frac=(frac>>9)+((frac&0x100)&&((frac&0x200)||(frac&0xff)));//向偶数舍入,进位
if(frac&0x800000) //如果进位
++exp;


return (sign<<31) | (exp<<23) | (frac&0x7fffff);
}


2.96
int float_f2i(float_bits f){
unsigned sign=f>>31;
unsigned exp=f>>23&0xff;
unsigned frac=f&0x7fffff;
if(exp<0x7f)
return 0;
else if(exp>158 ||(exp==158&&frac>0))
return 0x80000000;
int c=exp-0x7f;
if(c>23)
frac= ((1<<23)|frac)<<(c-23);
else
frac= (frac>>(23-c))|(1<<c);
return sign?(~frac+1):frac;
}


原创地址:http://blog.csdn.net/maidou0921/article/details/53907832

  • 9
    点赞
  • 81
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
### 回答1: 深入理解计算机系统(CSAPP)是由Randal E. Bryant和David R. O'Hallaron编写的经典计算机科学教材。该教材通过涵盖计算机体系结构、机器级别表示和程序执行的概念,帮助学生深入理解计算机系统的底层工作原理和运行机制。 深入理解计算机系统的练习题对于学生巩固并应用所学知识非常有帮助。这些练习题涵盖了计算机硬件、操作系统和编译器等多个领域,旨在培养学生解决实际问题和设计高性能软件的能力。 对于深入理解计算机系统的练习题,关键是通过实践进行学习。在解答练习题时,应根据课本提供的相关知识和工具,仔细阅读问题描述,并根据实际需求设计相应的解决方案。 在解答练习题时,需要多角度思考问题。首先,应准确理解题目要求,并设计合适的算法或代码来解决问题。其次,应考虑代码的正确性和效率,以及对系统性能的影响。此外,还要注意处理一些特殊情况和异常情况,避免出现潜在的错误或安全漏洞。 解答练习题的过程中,应注重查阅相关资料和参考优秀的解答。这可以帮助我们扩展对问题的理解,并学习他人的思路和解决方法。同时,还可以通过与同学和老师的讨论,共同探讨问题和学习经验。 总之,通过解答深入理解计算机系统的练习题,可以帮助学生巩固所学知识,同时培养解决实际问题和设计高性能软件的能力。这是一个学以致用的过程,可以加深对计算机系统运行机制和底层工作原理的理解。 ### 回答2: 理解计算机系统(CSAPP)是一本经典的计算机科学教材,通过深入研究计算机系统的各个方面,包括硬件、操作系统和编程环境,对于提高计算机科学专业知识与能力具有很大帮助。 练习题是CSAPP中的重要部分,通过练习题的完成,可以加深对计算机系统的理解,并将理论知识转化为实践能力。练习题的数量、难度逐渐递增,从简单的概念与基础问题到复杂的系统设计与实现。 在解答练习题时,首先需要对题目进行仔细阅读和理解,明确题目的要求和限制条件。然后,可以利用课堂讲解、教材内容、网络资源等进行查阅和学习相应的知识。同时,还可以参考课后习题解答等资料,了解一些常见的解题方法和思路。 在解答练习题时,可以利用计算机系统的工具和环境进行实际测试和验证。例如,可以使用调试器、编译器和模拟器等工具对程序或系统进行分析和测试。这样可以更加深入地理解问题的本质,并找到恰当的解决方法。 另外,解答练习题时还可以与同学、教师和网上社区进行交流和讨论。这样可以互相学习和交流解题思路,共同解决问题。还可以了解不同的解题方法和技巧,提高解题效率和质量。 练习题的解答过程可能会遇到一些困难和挑战,例如理论知识的不足、复杂问题的分析与解决。但是通过不断地思考和实践,相信可以逐渐提高解题能力,更好地理解计算机系统。 总之,深入理解计算机系统(CSAPP)练习题是提高计算机科学专业知识和能力的重要途径。通过仔细阅读和理解题目,查阅相关知识,利用计算机系统工具和环境进行实践,与他人进行交流和讨论,相信可以更好地理解计算机系统的各个方面,并将知识转化为实际能力。 ### 回答3: 《深入理解计算机系统(CSAPP)》是计算机科学领域的经典教材之一,对于深入理解计算机系统的原理、设计和实现起到了极大的帮助。在阅读这本书的过程中,书中的习题也是非常重要的一部分,通过做习题,我们可以更好地理解书中所讲的概念和思想。 CSAPP的习题涵盖了课本中各个章节的内容,从基础的数据表示和处理、程序的机器级表示、优化技术、程序的并发与并行等方面进行了深入探讨。通过解答习题,我们可以对这些知识进行实践应用,巩固自己的理解,并培养自己的解决问题的思维方式。 在解答习题时,我们需要充分理解题目要求和条件,并从知识的角度进行分析。有些习题可能需要进行一些编程实践,我们可以通过编程实现来验证和测试我们的思路和解决方案。在解答问题时,我们还可以查阅一些参考资料和网上资源,充分利用互联网的学习资源。 在解答习题时,我们需要保持积极的思维和态度。可能会遇到一些困难和挑战,但是通过坚持和努力,我们可以克服这些困难,提高我们的解决问题的能力。同时,我们还可以通过与同学或者其他人进行讨论,相互分享解题经验和思路,从而更好地理解问题。 综上所述,通过深入理解计算机系统(CSAPP)的习题,我们可以进一步巩固和深化对计算机系统的理解。掌握这些知识,不仅可以提高我们在计算机领域的能力,还可以为我们未来的学习和职业发展奠定重要的基础。因此,认真对待CSAPP的习题,是我们在学习计算机系统知识中不可或缺的一部分。
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值