文章目录
-
- Lab 总结博客链接
- 前引
- phase 1
- phase 2
- phase 3
- phase 4
- phase 5
- phase 6
- phase 7
- phase 8
- phase 9
- phase 10
- phase 11
- phase 12
- phase 13
Lab 总结博客链接
CSAPP Lab入门系统安装摸索 + Lab 博客链接
前引
这部分是我的二次编辑写的 这个
Lab1
是我在大一寒假完成的 除了Lab1
我没有重新做以外 后面的所有Lab
大一原来做过的我基本上都重新做了一遍 所以Forgive Me
这篇Lab
写的不是很好 那各位后面再见了~
由于昨天才把函数调试给弄好 环境配置 虚拟机那些
所以上午刷完了三道力扣 下午就来把Lab1给做了
如果有环境配置不会的同学 可以看一下我之前写的博客
下面给出链接
错不在我的 CSAPP环境配置 Ubuntu虚拟机安装 Vmwaretools安装图文教程
CSAPP 配套Lab下载 Self-Study Handout
phase 1
//自解代码如下 (违规使用 |符号)
int bitXor(int x, int y) {
return (~((~x & ~y) | (x & y)));
}//改进代码如下
int bitXor(int x, int y) {
return (~(~x & ~y) & ~(x & y));
phase 2
就是求 最小的补码表示数 那么意思就是 第一位是符号位 之后2~32位都是0 即可
int tmin(void) {
return 1<<31;
}
phase 3
这里好像是求x是否为补码最大值
是的话就返回1 不是就返回0
这里用了违规符号 但却是想不到其他的了 菜?的落泪
int isTmax(int x) {
return !(x ^ ~(1<<31));
}
phase 4
这里借鉴人家的思路用倍增做
我就是个菜? 确实思考了很久都没有搞懂 下面直接放代码吧
int allOddBits(int x) {
int b16 = x & (x >> 16);int b8 = b16 & (b16 >> 8);int b4 = b8 & (b8 >> 4);int b2 = b4 & (b4 >> 2);return (b2 >> 1) & 1;
}
phase 5
求相反数 我这里其实是发现了 相反数也就是
补码求反过来再加一个1
int negate(int x) {
return (~x)+1;
}
phase 6
这里我还是借鉴的人家的思路
但是这里我看得懂是什么意思了
就是对于 0~9 的ASCII码值十六进制是 0X30到 0x39之间的任何一个
转化为二进制就是 110xxx 或者 11000x (x是1或0)
然后只要满足这两种形式的任一一种即可
那么 就解决了哈 用异或来判断
int isAsciiDigit(int x) {
int a = !((x>>3) ^ 6);int b = !((x>>1) ^ 0x1c);return a | b;
}
phase 7
这里是用限定符号 做到 x ? y : z的作用
这里是利用了 ~0 全为1111111111的地方
如果 x 为正 那么!x + ~0就为1111111…
如果 x 为负 那么!x + ~0就为0
分析一下 这个代码还是好懂的
int conditional(int x, int y, int z) {
int temp = (!x + ~0);return (temp & y) | (~temp & z);
}
phase 8
这里我当时确实想不出来 感觉 这些题有点脑筋急转弯的味道
但还是看人家的代码 好好琢磨了一下 懂了什么意思
我刚开始就想用 利用y - x (等于 y + ((~x) + 1))判断符号位
来判断y是否大于等于x
但是有可能存在溢出情况 但是只会存在异号的情况下才会存在溢出
溢出的话 会把符号位给卡没 那么就不能通过判断符号位来判断y是否大于x了
但是溢出可以先提前判断 x和y的符号位 来直接判断大小
即 溢出 则直接判断y的符号位 没有溢出 则判断两个做减法后的符号位
int isLessOrEqual(int x, int y) {
int xflag = x>>31 & 1;int yflag = y>>31 & 1;int yminusx = y+ ((~x)+1);int flagtag = (xflag ^ yflag);yminusx = (yminusx>>31) & 1;return (flagtag & !yflag) | (!yminusx & !flagtag);
}
phase 9
这里我也再解释一下吧
当时我刚开始是想直接 >>31位的 但是有可能数值没有31位 那么移动位数就是31 mod 位数 那么就达不到检测是否有1存在
则通过上面代码的方式就可以检测到除了符号位 最高有效位是否是1了
int logicalNeg(int x) {
int move16 = x | x>>16; //一共只需移动31位 但是需要分开16+8+4+2+1 因为防止移动位数超过其数字位数 导致无效移动 所以没有直接 x | x>>31 算术右移int move8 = move16 | move16>>8;int move4 = move8 | move8>>4;int move2 = move4 | move4>>2;int move1 = move2 | move2>>1;return (move1 & 1) ^ 1;
}
phase 10
我歇逼了 真做不起了
看人家的解答也做不来了
后面的浮点数也做不起 看的脑壳疼做不来 ?
下面就放一下人家写的吧
int howManyBits(int x) {
int minusOne = ~0;int flagMask = (x >> 31 & 1) + minusOne; // x > 0 : 0xffffffff x < 0 : 0int posiX = (x & flagMask) | ~(x | flagMask); // x = x > 0 ? x : ~xint x1 = posiX | posiX >> 1;int x2 = x1 | x1 >> 2;int x3 = x2 | x2 >> 4;int x4 = x3 | x3 >> 8;int reguX = x4 | x4 >> 16; // change 0x001xx to 0x00111int ans = 0; int top = reguX >> 16;int mask = ( (!top) + minusOne ) & 16;reguX >>= mask;ans += mask;top = reguX >> 8;mask = ( (!top) + minusOne ) & 8;reguX >>= mask;ans += mask;top = reguX >> 4;mask = ( (!top) + minusOne ) & 4;reguX >>= mask;ans += mask;top = reguX >> 2;mask = ( (!top) + minusOne ) & 2;reguX >>= mask;ans += mask;top = reguX >> 1;mask = ( (!top) + minusOne ) & 1;reguX >>= mask;ans += mask;ans += reguX;return ans + 1;
}
phase 11
unsigned floatScale2(unsigned uf) {
unsigned flag = uf & 0x80000000;unsigned exp = uf >> 23 & 0xFF;unsigned frac = uf & 0x7fffff;if (exp == 0xff) // NaN or infinityflag = flag;else if (exp == 0) // unnormalizedfrac <<= 1;else if (exp == 0xfe) {
// become infinityfrac = 0;exp = 0xff;} else exp += 1; // normalizedreturn flag | (exp << 23) | frac;
}
phase 12
int floatFloat2Int(unsigned uf) {
unsigned flag = uf & 0x80000000;unsigned exp = uf >> 23 & 0xFF;unsigned frac = uf & 0x7fffff;if (exp > 157) // out of rangereturn 0x80000000;else if (exp < 127) // too smallreturn 0;else {
int e = exp - 127;int ans = (1 << e);if (e) ans += frac;frac <<= e;if (frac == 0x80000000)ans += (ans & 1);elseans += frac > 0x80000000;if (flag) ans = -ans;return ans;}
}
phase 13
unsigned floatPower2(int x) {
if (x < -149)return 0;if (x < -127)return 1 << (x + 149);if (x > 127)return 0x7f800000;return (x + 127) << 23;
}