计算机组成位运算实验,写的比较详细。
1题目与解答:
./*
* bitAnd - x&y using only ~ and |
* Example: bitAnd(6, 5) = 4
* Legal ops: ~ |
* Max ops: 8
* Rating: 1
*/
int bitAnd(int x, int y) {
return ~(~x|~y);
}
题意解析:
这就是实现与的功能,由逻辑概念A&B=!(!A|!B) 很容易解决
验证:
成功编译测试,得到1分 说明程序成功
2.题目与解答
/*
* getByte - Extract byte n from word x
* Bytes numbered from 0 (LSB) to 3 (MSB)
* Examples: getByte(0x12345678,1) = 0x56
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 6
* Rating: 2 (x>>8*n)&0xff
*/
int getByte(int x, int n) {
return ((x>>(n<<3))&0xff);
}
题意解析:
这题的意思就是取位值
对于0x12345678
当n=0时,return 0x78
当n=1时,return 0x56
当n=2时,return 0x34
当n=3时,return 0x12
解答过程与思考:
首先,在这个过程中,x应先右移8*n位再取最低的8位数值
即 return (x>>8*n)&0xff
但是 不能用* 所以采用移位
return ((x>>(n<<3))&0xff);
验证:
成功测试,题目完成
3.题目与解答
/
*
* logicalShift - shift x to the right by n, using a logical shift
* Can assume that 0 <= n <= 31
* Examples: logicalShift(0x87654321,4) = 0x08765432
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 20
* Rating: 3
*/
int logicalShift(int x, int n) {
int mask=~(((1<<31)>>n)<<1);
return (x>>n)&mask;
}
题意解析:
这题的意思就是逻辑右移位(默认为算术右移位)
解答过程与思考:
首先,考虑0x0000 0000 =>return x>>n
再考虑正数,0x0xxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
也只需要return x>>n
再考虑负数 1xxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx
取(0x-87654321,4)
1000 7 6 5 4 3 2 1 右移4位=》1111 1000 7 6 5 4 3 2
发现符号位对结果产生了干扰
所以 添加一个掩码(掩码只需要把符号位转为0)
对于这一个负数的 掩码应该为0x0FFFFFFF
若n=5 则掩码为0x07FFFFFFF….
观察这些掩码,很容易发现,若右移n位,则前n位应为0
所以
尝试将函数写为
int logicalShift(int x, int n) {
int mask=~(((1<<31)>>(n-1));
return (x>>n)&mask;
测试,报错 (不可用-号)
改正
int logicalShift(int x, int n) {
int mask=~(((1<<31)>>n)<<1);
return (x>>n)&mask;
(理由:最后要左移一位,因为首位已经是1了,如果左移n位,会多出现一个1)
验证:
成功测试,题目完成
4.题目与解答
/*
* 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) {
int result;
//int mask1=(0x55)|(0x55<<8)|(0x55<<16)|(0x55<<24);
int tmp_mask1=(0x55)|(0x55<<8);
int mask1=(tmp_mask1)|(tmp_mask1<<16);
//int mask2=(0x33)|(0x33<<8)|(0x33<<16)|(0x33<<24);
int tmp_mask2=(0x33)|(0x33<<8);
int mask2=(tmp_mask2)|(tmp_mask2<<16);
//int mask3=(0x0f)|(0x0f<<8)|(0x0f<<16)|(0x0f<<24);
int tmp_mask3=(0x0f)|(0x0f<<8);
int mask3=(tmp_mask3)|(tmp_mask3<<16);
int mask4=(0xff)|(0xff<<16);
int mask5=(0xff)|(0xff<<8);
//add every two bits
result=(x&mask1)+((x>>1)&mask1);
//add every four bits
result=(res