刚刚在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位有效数字