当前位置: 代码迷 >> 综合 >> CSAPP Lab1 实验记录 ---- Data Lab
  详细解决方案

CSAPP Lab1 实验记录 ---- Data Lab

热度:24   发布时间:2023-11-17 20:16:41.0

文章目录

    • 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;
}
  相关解决方案