实验一:bitAnd实验
只用~,|实现 & 操作
int bitAnd(int x, int y)
{
return ~((~x)|(~y));
}
该实验主要用到德摩根定律(∪的补等于补集的∩)
实验二:getByte实验
本关任务:补充函数getByte()
,取出x
中的n
号字节,将结果return
返回。
- 编号从低位到高位从
0
开始 - 操作符使用数量限制:
6
int getByte(int x, int n)
{
int m,s;
m=n<<3;//或者m=n*8;
s=x>>m;
return (s&0xff);
}
一个字节代表8位,对x中的字节编号是从低位到高位以0为始顺次递增,所以要取出其中的几号字节就将该字节放至最低位,然后与0xFF相与,该字节就会保留,而其他更高位字节就会变为0,这样即取出该字节。(将n号字节移至最低位即将x右移8*n位,8*n用位运算可表示位n<<3)
实验三:logicalShift函数
本关任务:补充函数logicalShift()
,将x
逻辑右移n
位(0<=n<=31) ,将结果return
返回。
- 操作符使用数量限制:
20
思路一:
int logicalShift(int x, int n)
{
int s1;
s1=~(((1<<31)>>n)<<1);
return (x>>n)&s1;
}
>>运算符默认是算数右移(即默认补1),而逻辑右移是默认补0,所以可以先进行算数右移然后再把1变为0,即构建一个前n位为0,后面为1的数(即代码中的s1)与(x>>n)相与。
思路二:
对于有符号数,>>默认是算数右移,对于无符号数,>>默认是逻辑右移。所以可以将x强制转换为无符号数,再右移
int logicalShift(int x, int n)
{
return ((unsigned int)x)>>n;
}
实验四:bitCount函数
本关任务:补充函数bitCount()
,统计x
的二进制表示中1
的数量,将结果return
返回。
- 操作符使用数量限制:
40
int bitCount(int x)
{
int count=0;
while(x){
x&=(x-1);
count++;
}
return count;
}
x&(x-1),每与一次,1的个数减1
实验十三:float_neg函数
本关任务:补充函数float_neg()
,返回-uf
的位级表示。
- 操作符使用数量限制:
10
注意:
- 本题及以下所有的题目都采用
unsigned int
来存放位级表示 - 所有的浮点类型都为
float
- 如果输入为
NaN
,返回NaN
unsigned float_neg(unsigned uf)
{
if((((uf>>23)&0xff)^0xff)||!(uf&((1<<23)-1))) uf=(1<<31)^uf;
return uf;
}
浮点数表示一共32位,1位表示符号,8位表示指数部分(阶码),23位表示尾数
当输入NaN(指数部分全为1,小数部分非0),返回NaN;其他情况更改符号位即可。
判断阶码(指数部分)是否全为1:思路类同实验二,因为0~22共23位表示浮点数的尾数,23~30共8位表示阶码,如果阶码部分全部为1,(((uf>>23)&0xff)^0xff)结果为0;
判断尾数部分是否全为0:((1<<23)-1)表示从右到左23位为1,其他高位为0,那么如果尾数部分全部为0,!(uf&((1<<23)-1))为1,反之为0
如果不满足NaN条件,则更改符号位,即(1<<31)^uf