当前位置: 代码迷 >> 综合 >> CSAPP:整数的位运算
  详细解决方案

CSAPP:整数的位运算

热度:4   发布时间:2023-12-06 12:19:26.0

刚刚在PCS帮学姐修好了电脑 开心~
一天写完了ICS的第二份作业,过程略曲折,记录一下错误的地方。

?? 位运算优先级高于加减运算

逻辑右移和算术右移的理解

2.63
srl用算术右移来完成逻辑右移,sra用逻辑右移来完成算术右移

unsigned srl(unsigned x, int k){
     /* Perform shift arithmetically*/unsigned xsra=(int)x>>k;return xsra&~( ~0<<(8*sizeof(int)-k));}int sra(int x, int k){
    /* Perform shift logically*/
int xsrl=(unsigned) x>>k;
return x>0?xsrl:(xsrl|(~0<<(8*sizeof(int)-k)));}

思路:用全0或全1填补移动位数即可

2.70
编程实现:Return 1 when x can be represented as an n-bit, 2’s-complement number;0 otherwise
Assume 1<=n<=w

int fits_bits(int x, int n){
    
return x>=(~ 0<<n)&&x<=(int)((unsigned)~0>>(sizeof(int)*8-n+1))?1:0;}

思路:限定了不能用幂运算,只能手动构造最大最小值
(int)((unsigned)~0>>(sizeof(int)*8-n+1))右移时需要把 ~0强制转换成unsigned类型(不然是算术位移会产生错误)
(sizeof(int)*8-n+1)要注意+1的问题(符号位)
( ~0<<n)可以这样表示最小值(符号扩展)
不明白为什么自己写了(int)还重跑了程序??,原因是之前移位时保留的数据类型是unsigned,直接比较不显示负值,返回出错


位运算与混合运算

2.79
不用乘除法,对整合参数x实现3* x/4,遵循位级整数编码规则

double mul3div4(int x){
    int y=(x<<1)+x;//先乘法return (((~0<<2)&y)>>2)+(1.0/4*(y&2))+(1.0/4*(y&1));}

思路:难点在除法,只能想出这么初级的办法,不具有兼容性…
截取整数(要右移两位,不然结果出错)+截取小数第一位计算数值(1/4,不是1/2)+截取小数第二位计算数值
重点:位运算优先级高于加减

2.82
判断表达式真值:
(ux-uy)==-(unsigned)(y-x)      真值为1

思路:ux-uy=(unsigned)(x-y),因为(unsigned)(x-y)>0,所以ux-uy=-(unsigned)(y-x)


C++的特殊输出

输出二进制:

#include<bitset>
cout<<bitset<输出位数>(输出数字或表达式)<<endl;

输出浮点数:

cout << showpoint << a << endl;    //默认输出六位有效数字
cout << setprecision(2) << a << endl;//保留两位有效数字,以科学计数法表示多余的部分
cout << setprecision(8) << a << endl; //输出8位有效数字