深入理解計算機系統 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;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM