CSAPP: Datalab

一、实验要求 实现如下几个问题: CSAPP: Datalab 对于int的问题,只能使用基本的位运算,对于float的,可是使用额外的控制语句。 二、预备知识 整型的表示方法:
  1. 无符号数:CSAPP: Datalab
  2. 有符号数:CSAPP: Datalab
无符号数和有符号数直接相互转换: CSAPP: DatalabCSAPP: DatalabCSAPP: DatalabCSAPP: Datalab 浮点数表示方法: 一般浮点数采用IEEE 754标准表示 V=CSAPP: Datalab
  1. S为符号位,占1bit。
  2. E为阶码,在单精度浮点数中占8位,双精度浮点数中占10位。
  3. M为尾数,范围时1~2-e或0~1-e。
CSAPP: Datalab 根据exp的值,float数可被分为3中情况,以单精度浮点数为例:
  1. 规格化的值。
  • 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。
    三、实验代码 异或 bitXor
    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: 位操作实现基本运算


    下一篇:基于MicroPython结合ESP8266模块实现TCP通信(AT指令版)