ICS lab1: Manipulating Bits
lab说明文档
lab1的要求
lab1分为15道独立的puzzle,每道puzzle限定使用的运算符号的个数,同时限定允许使用的运算符号,用这些运算符号完成指定的int运算。在完成一道题之后,可以使用 ./dlc 检查是否合乎标准,可以使用 ./btest 检查是否正确。
使用到的运算符号及其作用
~a : 对a按位取反
!a : 逻辑非a,a=0则为1,a!=0则为0
a&b :a和b按位进行与运算
a|b :a和b按位进行或运算
a^b :a和b按位异或运算
a+b :计算a+b,不考虑溢出情况
<< : 左移运算
>> :右移运算,在本lab里全部采用算数右移
开始写lab
首先注意到lab对于格式的要求:不能定义和使用函数;仅能进行限定个数的规定运算;不能使用逻辑运算符 if else while等;一切int的定义都必须在一切int运算之前(就是不能int x=…;x=…;之后再int y=…;)
puzzle1
/*
* bang - Compute !x without using !
* Examples: bang(3) = 0, bang(0) = 1
* Legal ops: ~ & ^ | + << >>
* Max ops: 12
* Rating: 4
*/
题解:
int bang(int x) {
/* right shift 31 bits of (0-1)&(~0) is 0xffffffff,others is not */
int y = x + (~0);
y = (y & (~x)) >> 31;
return (~y + 1);
}
这道题就是考察了0和其他数的不同,用 (0-1)&(~0) 或 0&((~0)+1)都可以得出结果。
puzzle2
/*
* bitCount - returns count of number of 1's in word
* Examples: bitCount(5) = 2, bitCount(7) = 3
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 40
* Rating: 4
*/
题解:
int bitCount(int x) {
/* count 1s using 0x11111111 and add them using 0x0f0f */
int y1 = (0x11) + ((0x11) << 8);
int y = y1 + (y1 << 16);
int z = x & y;
int flag = 0xf + (0xf << 8);
z = z + ((x >> 1) & y);
z = z + ((x >> 2) & y);
z = z + ((x >> 3) & y);
z = z + (z >> 16);
z = (z & flag) + ((z >> 4) & flag);
z = z + (z >> 8);
z = z & 0xff;
return z;
}
这道题比较繁琐,因为规则要求和步数限制,所以必须选择更好的方法,PPT上也有这题的详解: