深入理解计算机系统实验1datalab笔记

写在前面,以前没有接触过限定运算符的问题。所以出现了限定运算符,并且大多数逻辑运算都不可以使用,一些控制流语句都不可以使用,还是不太适应的。做了几天,还有三道做不下去了。

1.bitXor,思路:同时为0或者1的时候才为0,其他情况为1,所以可以先&操作(x & y),获得同时为1的。再将x,y进行~,然后再&,得到就是同时为0的(~x ^ ~y)。然后在这两个式子中都为0的就是01或10的。所以可以将这两个式子|运算再~就可以了。

/* 
 * bitXor - x^y using only ~ and & 
 *   Example: bitXor(4, 5) = 1
 *   Legal ops: ~ &
 *   Max ops: 14
 *   Rating: 1
 */
int bitXor(int x, int y) {
  int result = ~(x & y) & ~(~x & ~y);	
  return result;
}

2.tmin
直接1 << 31

/* 
 * tmin - return minimum two's complement integer 
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 4
 *   Rating: 1
 */
int tmin(void) {

  return 1<<31;

}

3.isTmax
观察发现Tmax * 2 + 2 == 0,测试函数时,发现-1和Tmax行为一致,所以需要去掉-1的影响,-1加上1就变成0了再!就变成1,所以可以这样做来去掉-1的影响。

//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 y = x + 1;
  return !((y + y) | !y); //括号中的表达式只有当x==Tmax时才会为0
}

4.allOddBits,我开始的思路是用^来x进行0xaaaaaaaa比较。所以有式子!(x ^ (x | 0xaaaaaaaa)),基于以下事实。
1. | 运算可以忽略掉偶数位的影响。比如需要n ,m 需要第一位是否相同,就可以|0xfffffffe,这样就可以保持其他位相同了。
2. 假如x的所有奇数位的都为1,x | 0xaaaaaaaa必然不会影响x位模式。

/*   
 * 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 n1 = 0xaa;
    n1 = (n1 << 8) | n1;
    n1 = (n1 << 16) | n1;
    //int n2 = n1 | 0xaa;
    //int n3 = (n2 << 16) | n2;
   
    return !(x ^ (x | n1)); //n1就是0xaaaaaaaa
}

5.negate
取反加一就行。

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

6.isAsciiDigit
在0x30-0x39的范围的数,他们减去0x30符号位为0,减去0x3为1。所以比较符号位满足这个条件就可以得到结果1。现在需要考虑溢出。溢出后会不会导致相同的结果。发现不用。

//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) {
  return !((x + ~0x30 + 1) >> 31) & !!((x + ~0x3a + 1) >> 31); 
  //return (!((x+~48+1)>>31))&!!((x+~58+1)>>31);
}

7.conditional
因为需要出y,或z,所以式子里面需要构造出的是可以选择的。矛盾的两个式子。不能同时为0。第一个式子,所以当x不为0时,将它变为1,再进行取反加1,可以得到0xffffffff,当x为0时,通过上述运算必定是为0。
第二个式子,当x为0,0变成-1,,1的位模式就是0xffffffff,那么就可以有了。当x不为0,其他式子都变成0;

/* 
 * 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) {
  return ((~!!x + 1) & y) | ((!!x + ~0x1 + 1) & z);
}

8.isLessOrEqual
x-y >= 0, 那么可以得到符号位为0(同为正数同为负数)。
当不同符号位,只要x是<=0,就可以输出1。
这题思路参考博客
https://blog.csdn.net/tzh476/article/details/51284938#commentBox

/* 
 * isLessOrEqual - if x <= y  then return 1, else return 0 
 *   Example: isLessOrEqual(4,5) = 1.
 *   Legal ops: ! ~ & ^ | + << >>
 *   Max ops: 24
 *   Rating: 3
 */
int isLessOrEqual(int x, int y) {
  
  int result = ((x >> 31) ^ (y >> 31));
  
  return (!result & !!((x + ~y + 1) >> 31)) | !(x ^ y) | (!!result & !((!!(x >> 31)) ^ 0x1));
}

9.islogicNeg
思路:找出0和其他非零值的不同。然后找不到哪里的不同
https://blog.csdn.net/tzh476/article/details/51284938#commentBox
这个博客给了我思考的切入点。
0的负数还是0,符号位相同,00,其他数的负数是相反数也就是符号位不同10,01。然后测试时需要测试Tmin,测试函数时都需要将Tmin做为测试的例子。
测试Tmin时,发现Tmin的相反数还是Tmin,符号位相同。,11,所以需要把Tmin给筛出来。

//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) {
  return (((~x + 1) | x) >> 31 & 0x1) ^ 0x1;
}

10.floatScale2
这道题的大多数思路还是由
https://blog.csdn.net/tzh476/article/details/51284938#commentBox
给出。感谢。这个需要很强大的观察能力了,才能得到这个。

/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) {
  unsigned frac = uf & 0x007fffff;
  unsigned exp = uf & 0x7f800000;
  unsigned sign = uf &(1 << 31); 
  if(!(exp ^ 0x7f800000)) {e
	return uf;
  }
  if(!(exp ^ 0x0)) {
	  if(frac & 0x00400000) {
	//	exp = (((exp >> 23) + 0x1) << 23) & 0x7f800000;
		exp +=  0x00800000;
		frac <<= 1;
	  }
	  else {
		frac <<= 1;
	  }
  }
  else {
       //exp = (((exp >> 23) + 0x1) << 23) & 0x7f800000;
        exp += 0x00800000;
	if(exp == 0xff) {
		frac = frac & 0x0;
	}
  }
  return (sign | exp | frac);
}

还有howmanybits, floatFloat2Int,floatPower2三道题没有做。。可能以后才回来做了。

你可能感兴趣的:(深入理解计算机系统实验lab)