写在前面的话:
这个实验网上已经有很多版本的实现方式了,对于我这个编程菜鸟而言这个实验真的很难,建议大家第一次做的时候先挑软柿子捏,把自己能想出来的先做完后再去想难的,真的想不出来就及时看网上其他人的实现思路。全部做完后隔几天再做一次,相信你能有全新的理解。
1.bitAnd
1.1【题目要求】
/*
bitAnd - 使用 ~ 和 | 实现 x&y
例子:bitAnd(6, 5) = 4
合法操作:~ |
最大操作数:8
难度评级:1
*/
1.2【解题方法】
运用德摩根定理,x&y <==> ~ ((~ x) | (~ y))
1.3 【代码】
int bitAnd(int x, int y) {
return ~((~x) | (~y));
}
2.getByte
2.1 【题目要求】
/*
getByte - 从一个字中提取第n个字节
字节从0(LSB)到3(MSB)编号
例子:getByte(0x12345678,1)= 0x56
合法操作:!〜&^ | + << >>
最大操作数:6
难度评级:2
*/
2.2 【解题方法】
先将n扩大8倍,由于不能使用*操作,所以只能用左移3位来代替;
再将x右移n位,这要所要求的那个字节就会来到最后八位,最后再用16进制数0xff与x相与即可;
2.3 【代码】
int getByte(int x, int n) {
n<<=3;
x>>=n;
return (x & 0xff);
}
3.logicalShift
3.1 【题目要求】
/*
logicalShift - 使用逻辑右移将 x 向右移动 n 位
可假设 0 <= n <= 31
例子:logicalShift(0x87654321,4) = 0x08765432
合法操作:!〜&^ | + << >>
最大操作数:20
难度评级:3
*/
3.2 【解题方法】
逻辑右移是不考虑所输入的数的符号位的,高位自动补0,在这个程序的开头的提示中说,假设所有的右移都为算数右移“2. Performs right shifts arithmetically.”,所以直接使用右移操作符>>会导致结果出错;所以就要对结果进行修正。修正的目的在于将右移后的高n为全部变为零,即我们要构造一个高n位为0低32-n位为1的数与算数右移n位后的x相与再返回最终结果;
3.3 代码
错误示例:
int logicalShift(int x, int n) {
int y=(1<<31)>>n;
x>>=n;
return (x & (~y));
}
在一开始我直接想当然的采取上述方法进行操作,发现结果是错误的,原因在于y再右移的过程中虽然也是移了n位,但是由于本身其第31位就存在一个1,导致右移n位后变成了高n+1位都为1;
例如假设右移三位,则y一开始为0x10000000,右移三位后变为0xf0000000,这就变成了高四位为1,而我们只想要高3位为1,这个时候就要对于y做进一步修正,使其左移1位;
int logicalShift(int x, int n) {
int y=(1<<31)>>n;
y<<=1;
x>>=n;
return (x & (~y));
}
而且我发现这个程序很矫情的一个点是,你所有的变量必须在一开始就声明,例如上面函数中的y,如果你不一开始就声明出来他,编译的时候就会报错:
例如:
int logicalShift(int x, int n) {
x>>=n;
int y=(1<<31)>>n;
y<<=1;
x>>=n;
return (x & (~y));
}
4.bitCount
4.1 【题目要求】
/*
bitCount - 返回 word 中 1 的个数
例如:bitCount(5) = 2,bitCount(7) = 3
合法操作:! ~ & ^ | + << >>
最大操作数:40
难度等级:4
*/‘
4.2 【解决方案+代码】
int bitCount(int x) {
int c,t1,t2,t3,t4,t5;
t1=0x55|((0x55)<<8);<

本文介绍了多个基于位运算的编程题目,包括bitAnd、getByte、logicalShift等,每个题目提供了详细的解题方法和代码实现,涉及位操作如德摩根定理、右移、逻辑非等,并讨论了特定限制条件下的解题策略。
最低0.47元/天 解锁文章
4259

被折叠的 条评论
为什么被折叠?



