CSAPP: Datalab
作者:互联网
一、实验要求
实现如下几个问题:
对于int的问题,只能使用基本的位运算,对于float的,可是使用额外的控制语句。
二、预备知识
整型的表示方法:
- 无符号数:
- 有符号数:
- S为符号位,占1bit。
- E为阶码,在单精度浮点数中占8位,双精度浮点数中占10位。
- M为尾数,范围时1~2-e或0~1-e。
- 规格化的值。
- exp处表示的值为e, e需要满足e>0 && e<255。
- 偏移量Bias=2^8-1=127,阶码 E=e-Bias。
- frac字段表示的值为f,尾数 M=1+f。
- 非规格化的值。
- exp处表示的值为e, e需要满足e=0。
- 偏移量Bias=2^8-1=127,阶码 E=1-Bias。
- frac字段表示的值为f,尾数 M=f。
- 特殊值。
- exp处表示的值为e, e需要满足e=255。
- 偏移量Bias=2^8-1=127,阶码 E=e-Bias。
- frac字段表示的值为f,f=0是,表示为无穷,f !=0 时,表示NaN。
int bitXor(int x, int y) { int result = (~(~x&y))&(~(x&~y)); return ~result; } //A ~A B ~B A&~B B&~A ~(A&~B) ~(B&~A) //1 0 0 1 0 1 1 0 //1 0 1 0 0 0 1 1 //0 1 0 1 0 0 1 1 //0 1 1 0 1 0 0 1有符号最小数 tmin
int tmin(void) { //1左移31位 int result = 1<<31; return result; }判断是不是有符号最大数 tmax
int isTmax(int x) { // x==max/x==0xffffff时,~x^(x+1)为0x0000000 // !!(~x)去掉x==0xfffffff的情况 int ret = !!(~x)&!(~x^(x+1)); return ret; }判断奇数位是否都为1 allOldBits
int allOddBits(int x) { //移位和加法构造模式数0xAAAAAAAA //用模式数&来过滤不同的数 int tmp = (170<<8)+170; int ret = 0; tmp = (tmp<<8)+170; tmp = (tmp<<8)+170; ret = !((tmp&x)^tmp); return ret; }求负数 negate
int negate(int x) { //取反码,加一 return (~x)+1; }判断是不是ascii数字 isAsciiDight
int isAsciiDigit(int x) { //高26位应当为0 int high = x&(~63); //第5,6位应当为1 int low = x&48; //最后4位加6不应当向第5位进位 int low2 = x&15; int ret = (!high)&(!(low^48))&(!((low2+6)&(~15))); return ret; }条件判断语句conditional
int conditional(int x, int y, int z) { //将x转为bool值,0,1 int bool_x = !x; //利用0、1构造掩码111111、0000000 //0->1111111->0000000;1->11111110->1111111 int mask = ~(~bool_x+1); //异或清除相同数字 int ret = (~mask&y)^(mask&z)^y^z; return ret; }判断是不是小于等于isLessOrEqual
int isLessOrEqual(int x, int y) { int nege_x = (~x)+1; int sum = y+nege_x; int sign_mask = 1<<31; //x的符号位 int sign_x = sign_mask&x; //y的符号位 int sign_y = sign_mask&y; //如果x<0且y>0,结果位true //如果x和y符号位相同,且y+(-x)<0,结果为true。符号位相同不会有溢出 int ret = (!!sign_x&!sign_y) | (!(sign_x^sign_y)&!(sign_mask&sum)); return ret; }逻辑非 logicNeg
int logicalNeg(int x) { //0的负数仍未0,符号位不变 //其他数的负数符号位会变 int ret = ~(((~x+1)|x)>>31)&1; return ret; }表示X需要最小的bit位 howMangBits
int howManyBits(int x) { int b16,b8,b4,b2,b1,b0; int sign=x>>31; //如果x为正则不变,否则按位取反(这样好找最高位为1的,原来是最高位为0的,这样也将符号位去掉了) x = (sign&~x)|(~sign&x); // 不断缩小范围 b16 = !!(x>>16)<<4;//高十六位是否有1 x = x>>b16;//如果有(至少需要16位),则将原数右移16位 b8 = !!(x>>8)<<3;//剩余位高8位是否有1 x = x>>b8;//如果有(至少需要16+8=24位),则右移8位 b4 = !!(x>>4)<<2;//同理 x = x>>b4; b2 = !!(x>>2)<<1; x = x>>b2; b1 = !!(x>>1); x = x>>b1; b0 = x; return b16+b8+b4+b2+b1+b0+1;//+1表示加上符号位 }单精度浮点数乘2 floatScale2
unsigned floatScale2(unsigned uf) { int sign = uf&(1<<31); int exp = (uf>>23)&255; //非规格化数 //左移1×2,加上符号位 if(exp==0) return uf<<1 | sign; //Nan值和无穷大 if(exp==255) return uf; //规格化数 //exp+1 return uf+(1<<23); }浮点数转int floatFloat2Int
int floatFloat2Int(unsigned uf) { int sign = (uf>>31)&1; //偏执量为127 int exp = ((uf>>23)&255) - 127; int frac = uf&(~(511<<23)); //溢出过大 if(exp>31) return 0x80000000u; //exp小于0 if(exp<0) return 0; //frac加上默认的1 frac += (1<<24); //小于24,右移 if(exp<=24) frac = frac >> (24-exp); //大于24,左移 else if(exp<=30) frac = frac << (exp-23); //如果符号位为1,转负数 if(sign) frac = ~frac+1; return frac; }2幂次的浮点数表示 floatPower2
unsigned floatPower2(int x) { // int ret =1; //太大 if(x>128) return 0x7f800000; //太小 if(x<-126) return 0; //加上偏移127 return (x+127)<<23; }四、实验结果
Correctness Results Perf Results Points Rating Errors Points Ops Puzzle 1 1 0 2 8 bitXor 1 1 0 2 1 tmin 1 1 0 2 8 isTmax 2 2 0 2 9 allOddBits 2 2 0 2 2 negate 3 3 0 2 13 isAsciiDigit 3 3 0 2 10 conditional 3 3 0 2 16 isLessOrEqual 4 4 0 2 6 logicalNeg 4 4 0 2 36 howManyBits 4 4 0 2 10 floatScale2 4 4 0 2 20 floatFloat2Int 4 4 0 2 5 floatPower2 Score = 62/62 [36/36 Corr + 26/26 Perf] (144 total operators)
标签:CSAPP,return,符号,int,浮点数,Datalab,ret,exp 来源: https://www.cnblogs.com/skyliulu/p/12966053.html