zoukankan      html  css  js  c++  java
  • 深入理解计算机系统 csapp datalab 详解

    深入理解计算机系统 csapp datalab 详解

    实验链接:教材网站

    educoder在线测评平台:educoder

    题解

    bitXor

    //1
    /* 
     * bitXor - x^y using only ~ and & 
     *   Example: bitXor(4, 5) = 1
     *   Legal ops: ~ &
     *   Max ops: 14
     *   Rating: 1
     */
    int bitXor(int x, int y) {
      return ~((~(~x&y))&(~(x&~y)));
    }
    /*使用离散数学的方法,列出真值表,得到
    xor = (~x&y)|(x&~y)
    再使用德摩根律消去或即可
    

    tmin

    /* 
     * tmin - return minimum two's complement integer 
     *   Legal ops: ! ~ & ^ | + << >>
     *   Max ops: 4
     *   Rating: 1
     */
    int tmin(void) {
    
      return 0x1<<31;
    
    }
    //很简单,没什么好说的
    

    isTmax

    //2
    /*
     * isTmax - returns 1 if x is the maximum, two's complement number,
     *     and 0 otherwise 
     *   Legal ops: ! ~ & ^ | +
     *   Max ops: 10
     *   Rating: 1
     */
    int isTmax(int x) {
      int eqz = !!((~x)^0x0);//如果x=ffffffff,eqz = 0,否则eqz = 1
      return (!((x+1)^(~x)))&(eqz);
    }
    /*
    首先整体的思路是,如果一个数+1和取反后得到的结果一样,那么说明是最大值或者最小值(ffffffff+1 = 00000000)
    同时,再排除掉ffffffff的情况即可判断是否为最大值
    */
    

    allOddBits

    /* 
     * allOddBits - return 1 if all odd-numbered bits in word set to 1
     *   where bits are numbered from 0 (least significant) to 31 (most significant)
     *   Examples allOddBits(0xFFFFFFFD) = 0, allOddBits(0xAAAAAAAA) = 1
     *   Legal ops: ! ~ & ^ | + << >>
     *   Max ops: 12
     *   Rating: 2
     */
    int allOddBits(int x) {
      int tmp;
      int detect = 0xAA<<8|0xAA;
      detect = detect<<16|detect;
      tmp = x|detect;
      return !(tmp^x);
    }
    /*
    思路:先构造出一个全部奇数位为1,偶数位为0的数字detect用于检测
    将x|detect,若x全部奇数位都为1,那么使用或操作不会使tmp和x有差别,否则tmp!=x
    最后,检测tmp和x是否相等即可
    */
    

    negate

    /* 
     * negate - return -x 
     *   Example: negate(1) = -1.
     *   Legal ops: ! ~ & ^ | + << >>
     *   Max ops: 5
     *   Rating: 2
     */
    int negate(int x) {
      	return (~x)+0x1;
    }
    //按位取反+1
    

    isAsciiDigit

    //3
    /* 
     * isAsciiDigit - return 1 if 0x30 <= x <= 0x39 (ASCII codes for characters '0' to '9')
     *   Example: isAsciiDigit(0x35) = 1.
     *            isAsciiDigit(0x3a) = 0.
     *            isAsciiDigit(0x05) = 0.
     *   Legal ops: ! ~ & ^ | + << >>
     *   Max ops: 15
     *   Rating: 3
     */
    int isAsciiDigit(int x) {
        int xt = x&0xff; 
        int xh = xt>>4;
        int xl = xt&0x0f;
        int smaller = ((0x9+(~xl+1))>>31)&0x1;
        return !(xt^x)&!(xh^0x3)&(!smaller);
    }
    /*
    首先取出x的最低8位,作为xt
    xt的高4位,作为xh,低4位作为xl
    smaller用来判断9是否<smaller,若是,则取1
    最终的条件是,x>0(通过xt^x判断),xh==3(通过xh^0x3判断),以及xl<=9
    */
    

    conditional

    /* 
     * conditional - same as x ? y : z 
     *   Example: conditional(2,4,5) = 4
     *   Legal ops: ! ~ & ^ | + << >>
     *   Max ops: 16
     *   Rating: 3
     */
    int conditional(int x, int y, int z) {
      int t= !!x;
      t = (t<<31)>>31;
      return (t&y)+(~t&z);
    }
    /*
    思路
    由x!=0,return y,x=0时return z可知
    仅需构造ret = t*y+(1-t)*z即可
    t = (x!=0)
    */
    

    isLessOrEqual

    int isLessOrEqual(int x, int y) {
        int subFlag = !((y+((~x)+0x1))&(0x1<<31));//判断y-x是否为正数,有可能溢出 溢出情况为 y正 x负,或y负x正
        int ySignal = (y>>31)&0x1;
        int xSignal = (x>>31)&0x1;
        int yBig = !ySignal&xSignal;
        int xBig = !xSignal&ySignal;
    	  return subFlag&(!(xBig))|yBig;;
    }
    /*
    思路:
    直接将x,y相减,判断符号大小,并且可能有溢出,因此需要对溢出进行单独判断
    */
    

    logicalNeg

    //4
    /* 
     * logicalNeg - implement the ! operator, using all of 
     *              the legal operators except !
     *   Examples: logicalNeg(3) = 0, logicalNeg(0) = 1
     *   Legal ops: ~ & ^ | + << >>
     *   Max ops: 12
     *   Rating: 4 
     */
    int logicalNeg(int x) {
      int negx = ~x+1;
      int ret = negx^x;
      return 0x1^(((ret>>31)&0x1)|((x>>31)&0x1));
    }
    /*
    思路
    0和其他数字的一个重大区别是 0取补码之后还是和自身相等
    当然,0xffffffff也有可能取补码后和自身相等。因此对0xffffffff进行单独判断((x>>31)&0x1)
    */
    

    howManyBits

    int howManyBits(int x) {
      int b16,b8,b4,b2,b1,b0;
      int sign=x>>31;
      x = (sign&~x)|(~sign&x);//如果x为正则不变,否则按位取反(这样好找最高位为1的,原来是最高位为0的,这样也将符号位去掉了)
    
    
    // 不断缩小范围
      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表示加上符号位
    }
    /*
    代码来源于网络
    通过二分法,查找出1的最高位
    */
    

    floatScale2

    //float
    /* 
     * floatScale2 - Return bit-level equivalent of expression 2*f for
     *   floating point argument f.
     *   Both the argument and result are passed as unsigned int's, but
     *   they are to be interpreted as the bit-level representation of
     *   single-precision floating point values.
     *   When argument is NaN, return argument
     *   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
     *   Max ops: 30
     *   Rating: 4
     */
    unsigned floatScale2(unsigned uf) {
      int signal = (uf)&(1<<31);
      unsigned exp = (uf>>23);
      unsigned clearBits;
      
      if((exp&0xff)==0x0)
      {
        return (uf<<1)|signal;
      }
      //NAN
      if((exp&0xff)==0xff)
      {
          return uf;
      }
    
      exp = exp+1;
      //NAN
      if((exp&0xff)==0xff)
      {
          return 0x7f800000|signal;
      }
      exp = exp<<23;
      clearBits = 0x807fffff;
    
      uf = uf&clearBits;
      uf = uf|exp;
      return uf;
    }
    /*思路
    取符号位,exp,若为NAN或0,可简单操作后直接返回。
    若exp+1后成为nan,也可直接范围。
    否则将exp替换为新的exp即可。
    */
    

    floatFloat2Int

    /* 
     * floatFloat2Int - Return bit-level equivalent of expression (int) f
     *   for floating point argument f.
     *   Argument is passed as unsigned int, but
     *   it is to be interpreted as the bit-level representation of a
     *   single-precision floating point value.
     *   Anything out of range (including NaN and infinity) should return
     *   0x80000000u.
     *   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
     *   Max ops: 30
     *   Rating: 4
     */
    int floatFloat2Int(unsigned uf) {
        unsigned exp = (uf>>23)&0xff;
        unsigned tmp;
        int shift;
        int signal;
        int clearBits;
        int setBits;
        if((exp)<127) return 0;
        if((exp)>159) return 0x80000000u;
        tmp = uf;
        signal = (uf>>31)&0x1;
        shift = 23-(exp-127);
        if((exp&0xff)!=0)
        {
            exp = exp-127;
            tmp = tmp>>shift;
            clearBits = ~(0xffffffff<<(exp));
            setBits = 0x1<<(exp);
            tmp = tmp&clearBits;
            tmp = tmp|setBits;
            if(signal==0) return tmp;
            else return (~tmp)+1;
        }else
        {
            return 0;
        }
        
    }
    

    floatPower2

    /* 
     * floatPower2 - Return bit-level equivalent of the expression 2.0^x
     *   (2.0 raised to the power x) for any 32-bit integer x.
     *
     *   The unsigned value that is returned should have the identical bit
     *   representation as the single-precision floating-point number 2.0^x.
     *   If the result is too small to be represented as a denorm, return
     *   0. If too large, return +INF.
     * 
     *   Legal ops: Any integer/unsigned operations incl. ||, &&. Also if, while 
     *   Max ops: 30 
     *   Rating: 4
     */
    unsigned floatPower2(int x) {
      unsigned exp;
      unsigned signal;
      unsigned ret;
      if(x>127) return 0x7f800000;
      if(x<-126) return 0;
      exp = x+127;
      signal = 0x0<<31;
      exp = exp<<23;
      ret = 0;
      return ret|exp|signal;
    }
    
  • 相关阅读:
    redis info详解
    redis数据类型-有序集合
    redis数据类型-集合类型
    redis数据类型-列表类型
    python——井字小游戏
    python——元组和字典学习笔记
    docker学习笔记
    中型公司网络架构拓扑与详解
    python——将图片转换为字符编码(linux版的)
    python——冒泡排序练习
  • 原文地址:https://www.cnblogs.com/alex101/p/14293392.html
Copyright © 2011-2022 走看看