CSAPP: datalab实验报告

实验一: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

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值