本文共 4089 字,大约阅读时间需要 13 分钟。
文章目录
Lab1-3 总结博客链接
前引
由于昨天才把函数调试给弄好 环境配置 虚拟机那些 所以上午刷完了三道力扣 下午就来把Lab1给做了 如果有环境配置不会的同学 可以看一下我之前写的博客 下面给出链接
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 : 0 int posiX = (x & flagMask) | ~(x | flagMask); // x = x > 0 ? x : ~x int 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 0x00111 int 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 infinity flag = flag; else if (exp == 0) // unnormalized frac <<= 1; else if (exp == 0xfe) { // become infinity frac = 0; exp = 0xff; } else exp += 1; // normalized return 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 range return 0x80000000; else if (exp < 127) // too small return 0; else { int e = exp - 127; int ans = (1 << e); if (e) ans += frac; frac <<= e; if (frac == 0x80000000) ans += (ans & 1); else ans += 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;}
小结
我是啥篮子
转载地址:https://love6.blog.csdn.net/article/details/113247639 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!