lab1
目录
1. question1
思路
由于是按补码形式存储,最高位为1 其他位全为0 ,直接将1 左移31 位即可得到
代码
int tmin(void) {
return 1<<31;
}
测试截图
./dlc -e bits.c:
btest:
2. question2
思路
Tmax 的补码表示为最高位为0 其他位全为1 即0x7fffffff ,可得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
所以当x 为0x7fffffff 时返回值为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 不等于0时x1 全为1,和y 与运算得到y 本身,按位取反之后为0 和z 相与之后为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 或者Nan 即exp==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)

浙公网安备 33010602011771号