lab1

目录

1. question1

思路

由于是按补码形式存储,最高位为1 其他位全为0 ,直接将1 左移31 位即可得到

代码

int tmin(void) {

  	return 1<<31;
}

测试截图

./dlc -e bits.c:

btest:

2. question2

思路

Tmax 的补码表示为最高位为0 其他位全为10x7fffffff ,可得Tmax+1=Tmin(0x80000000) ,同时

若 x= 0111 1111 1111 1111 1111 1111 1111 1111

x+1= 1000 0000 0000 0000 0000 0000 0000 0000

!(x^(x+1))=1

!(x+1)=0 !!(x+1)=1

所以当x0x7fffffff 时返回值为1,其余返回值为0

代码

int isTmax(int x) {
  return !((~(x+1)^x))&!!(x+1);
}

测试截图

./dlc -e bits.c:

btest :

3. question3

思路

最重要的是构造一个32 位并且奇数位为1 的数,若有一个数为a 其奇数位全为1 如果存在x 使得x&a==a 那么x 就满足条件

先构造8 位奇数位为1 的数之后左移与原状态取或运算即可得到满足条件的16 位数,以此类推变可得到32 位奇数位为1 的数,之后用x&a 若返回结果为x 则说明x 满足条件,随后和自身异或得到0 取非得到返回值1 ,运行成功。

代码

int allOddBits(int x) {
	int a=0xAA;
	int b=(a<<8)|a;
	int c=(b<<16)|b;
	return !((x&c)^(c));
}

测试截图

./dlc -e bits.c:

btest:

4. question4

思路

函数理解为,当x!=0 时返回y 否则将返回z ,当首先将x 的范围限制住,可以采用!x 来判断是否为零

x 等于0 时,x1 最高位为1,其余位为0-0,此时和y与运算得0 按位取反之后最高位为0 其余为为1 ,和z 做与运算得到本来z 的值返回即可

x 不等于0x1 全为1,和y 与运算得到y 本身,按位取反之后为0z 相与之后为0 所以最后取和返回y

主要还是通过!x 来缩小x1 的范围再进行判断就方便很多

代码

int conditional(int x, int y, int z) {
  int x1=!x+~0;
	return (x1&y)+((~x1)&z);
}

测试截图

./dlc -e bits.c:

bteat:

5. Nuaa_question5

思路

首先提取符号位sign和阶码exp ,情况如下:

若为inf 或者Nanexp==0xff 直接返回自身

若为非规格化数,exp==0 时,直接将尾数左移一位,但是注意恢复原来的符号位

若为规格化数,exp>0&&exp<0xff 直接将阶码加一即可,阶码加一后如果为0xff 就代表浮点数乘二会溢出,返回inf 主以依然要保留原来的符号位,如果不溢出就讲符号,阶码,尾数三部分按照格式组合起来即可。

代码

unsigned float_twice(unsigned uf) {
	int exp = (uf>>23)&0xff;
	int sign = uf&(1<<31);
	if(exp==255) return uf;
	if(exp==0) return sign|(uf<<1);
	exp+=1;
	if(exp==255) return sign|0x7f800000;
   	return(uf&0x807fffff)|(exp<<23) ;
}

测试截图

./dlc -e bits.c:

btest:

6. Nuaa_question6

思路

首先和第五题类似通过移位和& 运算取得符号位sign ,阶码exp 和尾数frac 实际上的阶码等于exp-127 ,关与于阶码:

exp<127 实际阶码小于零,浮点数的绝对值小于1,直接转换为整数的零即可

exp>157 实际阶码大于30 ,此时浮点数的绝对值最小为2^31 如果是正数就会发生溢出返回0x80000000u ,但是如果为负数,-2^31 转为整数并不溢出,结果为0x80000000u ,其他负数全部溢出,所以综上所述返回值全部为0x80000000u

exp>=127&&exp<=150 时实际阶码大于等于0小于等于23,单独提取出来的尾数相当于阶码为23 ,所以整数右移(127+23-exp) 位即可

exp>150&&exp<=157 时实际阶码大于等于23 小于等于30 相当于整体左移(exp-127-23) 即可

代码

int float_f2i(unsigned uf) {
	int exp,sign,frac,ans;
	exp=(uf>>23)&0xff;
    sign=(uf>>31)&1;
	frac=(uf&0x7fffff)|0x800000;
	if(exp<127)
		return 0;
	if(exp>157)
		return 0x80000000u;
	if(exp<150)
		ans=frac>>(150-exp);
	else
		ans=frac<<(exp-150);
	if(!sign)
		return ans;
	else
		return ((~ans)+1);
}

测试截图

./dlc -e bits.c:

btest:

7. 最终结果

./driver.pl截图:

挑战教授截图(161920214)

8. 备注

posted @ 2021-08-05 10:38  shangjin2001  阅读(105)  评论(0)    收藏  举报