试验获取请到官网 CSAPP
1.bitXor
int bitXor(int x, int y) {return (~(x&y)) & (~((~x)&(~y)));}
int tmin(void) {return 1<<31;}
int isTmax(int x) {return !(((~(x+1))^x) | (!(~x)));}
- 或运算
|左边筛选出0x7fffffff和0xffffffff得到全0 , 右边对于0x7fffffff得到全0, 对于0xffffffff得到1 ,经过或运算之后只有目标Tmax0x7fffffff会得到0,取非之后返回4.AllOddBits
int allOddBits(int x) {int allodd0 = (0x55<<24) + (0x55<<16) + (0x55<<8) +0x55;return !(~(allodd0 | x));}
int negate(int x) {return (~x) + 1;}
int isAsciiDigit(int x) {int a = (x>>3)^0x6;int b = x^0x38;int c = x^0x39;return !a | !b | !c;}
int conditional(int x, int y, int z) {int negative1 = ~1 + 1; //-1int control = !x + negative1; //x=0 ,c=0 ;x!=0 ,c=0xffffffffreturn (y&control) + (z&(~control));}
int isLessOrEqual(int x, int y) {int negativex = ~x+1;int a = !((!(x>>31))|(y>>31)); //x<0 且 y>=0int b = (( !((x>>31)^(y>>31)) ) & (!((y+negativex)>>31) | !(x^(1<<31))));// x,y异号 且 ( y-x>=0 或 x=0xffffffff )return a | b;}
int logicalNeg(int x) {return ((x|(~x+1))>>31)+1;;}
int howManyBits(int x) {int shift1,shift2,shift4,shift8,shift16;int sum;int t=((!x)<<31)>>31;//x为0时,t(二进制)全为1,x不为0时,全为1int t2=((!~x)<<31)>>31;//当x为-1时,t2全为1,否则,全为0int op=x^((x>>31));//正数不变,负数取反shift16=(!!(op>>16))<<4;//如果高十六位全为0,则0左移4位,不全为0,则1左移4(表示op要右移2^4位)位op=op>>shift16;shift8=(!!(op>>8))<<3;op=op>>shift8;shift4=(!!(op>>4))<<2;op=op>>shift4;shift2=(!!(op>>2))<<1;op=op>>shift2;shift1=(!!(op>>1));op=op>>shift1;sum=2+shift16+shift8+shift4+shift2+shift1;return(t2&1)|((~t2)&((t&1)|((~t)&sum)));}
- 略有点复杂,最后参考了这篇 ,这个二分法挺巧妙的
11.floatScale2
unsigned floatScale2(unsigned uf) {int e = (uf>>23) & 0xff;int rte = e+1;if(!e)//e=0return (uf&0xf0000000) + ((uf&0x7fffff)<<1);else if(!(e^0xff))return uf;else if(rte&(1<<8))return ((uf>>31)<<31) + (0xff<<23);elsereturn (uf&(0x807fffff)) + (rte<<23);}
int floatFloat2Int(unsigned uf){int e = (uf >> 23) & 0xff; //阶码int f = uf & 0x7fffff; //尾码int tag = uf & 0x80000000; //符号位if (e <= 126) //小于0return 0;else if (e > 157) //上溢return 0x80000000;else //范围内{int s = e - 127;f = f + 0x800000;if (s >= 23){int r = f << (s - 23);if (tag)return -r;elsereturn r;}else{int r = (f >> (23 - s));if (tag)return -r;elsereturn r;}}}
unsigned floatPower2(int x) {unsigned INF = 0xff << 23; // 阶码全1int e = 127 + x; // 得到阶码if (x < 0) // 阶数小于0直接返回0return 0;if (e >= 255) // 阶码>=255直接返回INFreturn INF;return e << 23;// 直接将阶码左移23位,尾数全0,规格化时尾数隐藏有1个1作为底数}
- 不难
最后一题有个小插曲,就是最后一个题目测试时会提示死循环
但是逻辑是没有问题的,最后看了下测试文件的代码,在 btest.c 文件的开头限制了超时时间为10s,
将TIMEOUT_LIMIT修改为100,测试通过
最后是完整文件
小结
慕名而来看了CSAPP,不得不说看了这本书写的真的很好,看完第二章我对浮点数的认知确实更清晰了,后续我做了其他lab之后,也会逐一发上来,欢迎大家关注。
