CSAPP || Datalab

1. bitXor

  • 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);
}

2. tmin

  • tmin - return minimum two’s complement integer
  • Legal ops: ! ~ & ^ | + << >>
  • Max ops: 4
  • Rating: 1
int tmin(void) {
 return 1 << 31;
}

3. isTmax

  • isTmax - returns 1 if x is the maximum, two’s complement number,
  • and 0 otherwise
  • Legal ops: ! ~ & ^ | +
  • Max ops: 10
  • Rating: 1

解题思路:Tmax = ~(Tmax+1), 排除同样满足此条件的0xffffffff

int isTmax(int x) { 
   	return !(x ^ (~(x + 1))) & !!(~x);
}

同理, Tmin = ~Tim + 1, 排除同样满足此条件的0x0

int isTmin(int x) {
   	return  !(x ^ (~x + 1)) & !!(x);
}

4. 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

解题思路:

  • x & 0xAAAAAAAA = 0xAAAAAAAA。
  • 构造0xAAAAAAAA
int allOddBits(int x) {
	int a = 0xAA | 0xAA << 8;
	a = a | 0xAA << 16;
	a = a | 0xAA << 24;
	return !((a&x)^a);
}

5. negate

  • negate - return -x
  • Example: negate(1) = -1.
  • Legal ops: ! ~ & ^ | + << >>
  • Max ops: 5
  • Rating: 2

解题思路:

-x = x的补码,补码=反码+1

int negate(int x) {
  return (~x+1);
}

6. isAsciiDigit

  • 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

解题思路:

依据两个原理:

  • 计算机的减运算等于加补码,补码=反码+1
  • 对于32位int来说,若一个数>=0,右移31位为0;若为负数,右移31位为1。
int isAsciiDigit(int x) {
	int left = x + (~(0x30)+1);
	int right = (~x+1) + 0x39;
	return !(left >> 31) & !(right >> 31);
}

7. conditional

  • conditional - same as x ? y : z
  • Example: conditional(2,4,5) = 4
  • Legal ops: ! ~ & ^ | + << >>
  • Max ops: 16
  • Rating: 3

解题思路:

  • 当x只取0x00000000或0xFFFFFFFF时,结果为(x & y) | (~x & z)。
  • 只需要排除当x != 0时,x = 0xFFFFFFFF。
int conditional(int x, int y, int z) {
	x = (!!x) << 31 >> 31;
	return ((x & y) | (~x & z)); 
}

8. isLessOrEqual

  • isLessOrEqual - if x <= y then return 1, else return 0
  • Example: isLessOrEqual(4,5) = 1.
  • Legal ops: ! ~ & ^ | + << >>
  • Max ops: 24
  • Rating: 3

解题思路:

  • 理论上y-x >= 0即可。
  • 但是如果x, y正负不同,相减可能会溢出。
  • 所以分两种情况讨论,如果两个数符号相等,判断相减;如果两个数符号不同,判断符号。
int isLessOrEqual(int x, int y) {
	int a = !((x >> 31) ^ (y >> 31));
	return (a & !((y + (~x + 1)) >> 31)) | (~a & !(y >> 31));
}

9. logicalNeg

  • 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

解题思路:

0和-0的最高位为0,将正数转化为负数,那么只有0的最高位为0

int logicalNeg(int x) {
  	return ~((x | (~x + 1)) >> 31) & 0x1;
}

10. howManyBits

  • howManyBits - return the minimum number of bits required to represent x in two’s complement
  • Examples: howManyBits(12) = 5
    • howManyBits(298) = 10
    • howManyBits(-5) = 4
    • howManyBits(0) = 1
    • howManyBits(-1) = 1
    • howManyBits(0x80000000) = 32
  • Legal ops: ! ~ & ^ | + << >>
  • Max ops: 90
  • Rating: 4

解题思路:

  • 补码的最高表示位前面的所有数字应该都是全0(正数)或是全1(负数)。
  • 将原数与左移一位后的数字异或则最高的不同的那个位置为1,我们只需要找到这个最高的不同位即可。
int howManyBits(int x) {
	int temp = x ^ (x << 1);
	int bit_16,bit_8,bit_4,bit_2,bit_1;
	bit_16 = !!(temp >> 16) << 4;
	temp = temp >> bit_16;
	bit_8 = !!(temp >> 8) << 3;
	temp = temp >> bit_8;
	bit_4 = !!(temp >> 4) << 2;
	temp = temp >> bit_4;
	bit_2 = !!(temp >> 2) << 1;
	temp = temp >> bit_2;
	bit_1 = !!(temp >> 1);
	return 1 + bit_1 + bit_2 + bit_4 + bit_8 + bit_16;
}

11. floatScale2

  • 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

解题思路:

  • IEEE浮点数格式一共分为三种形式,弱规范数,NAN以及一般的数。
  • NAN直接返回
  • 弱规范数直接左移1位但要保留符号位。
  • 一般数的话尾数不变,只移动指数位并保持符号位不变。
unsigned floatScale2(unsigned uf) {
	unsigned a = (uf >> 23) & 0xff;
	unsigned flag = uf >> 31 << 31;
	int temp = uf;
	if (a == 0xff) 
		return uf;
	else if (a == 0)
	{
		temp = uf << 1;
		//temp = temp & (~(0xff << 23));
		temp = temp | flag;
	}
	else 
	{
		temp = temp + (0x1<<23);
		temp =  temp | flag;
	}
		
	return temp;;
}

12. 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

解题思路:

  • 此题的解题关键在于分几种情况,先将符号位拿出单独讨论,当指数位-127>=32位时,溢出,返回0x80000000u,当指数位-127 < 0时,是小于1的小数,返回0即可。
  • 剩下的情况一种是指数位-127>=23位时,将尾数位左移多出的位;当<23时,尾数位右移缺失的位。
  • 再将最后的结果根据符号位的判断加上正负。
int floatFloat2Int(unsigned uf) {
	int a = ((uf >> 23) & 0xff) - 127;
	int flag = uf >> 31;
	if (a >= 32)
		return 0x80000000u;
	else if (a < 0)
		return 0;
	else 
	{
		int temp = (uf | 0x800000) & 0xffffff;
		if (a >= 23)
		{
			int e = a - 23;
			temp = temp << e;
		}
		else 
		{
			int e = 23 - a;
			temp = temp >> e;
		}
		return flag ? -temp : temp;
	}
}

13. 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) {
    	if (x > 127)
	{
		return 0x7f800000;	
	}
	else if (x < -127)
	{
		return 0x0;	
	}
	else
	{
		return (x + 127) << 23;
	}
}
  • 6
    点赞
  • 9
    收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:像素格子 设计师:CSDN官方博客 返回首页
评论 2

打赏作者

perry0528

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值