计组实验2报告Word下载.docx
- 文档编号:409722
- 上传时间:2023-04-28
- 格式:DOCX
- 页数:16
- 大小:160.65KB
计组实验2报告Word下载.docx
《计组实验2报告Word下载.docx》由会员分享,可在线阅读,更多相关《计组实验2报告Word下载.docx(16页珍藏版)》请在冰点文库上搜索。
~(x&
y)=(`x)|(~y)(x&
y)=~((`x)|(~y))
#代码:
intbitAnd(intx,inty){
return~((~x)|(~y));
(2).getByte函数,要求如下:
*getByte-Extractbytenfromwordx
*Bytesnumberedfrom0(LSB)to3(MSB)
*Examples:
getByte(0x12345678,1)=0x56
!
~&
^|+<
<
>
>
6
2
*/
要求从数X中取出第n个字节
#思路:
1.首先,将需要保留的字节移到最低位字节(编号为00的字节)上,即右
移n个byte(每个byte有8位),也就是n*8(n<
3)位;
2.清除高三位字节的信息而保留最低位字节的信息,即与0xff进行&
运算即可。
intgetByte(intx,intn){
returnx>
(n<
3)&
0xff;
}
(3).logicalShift函数,要求如下:
*logicalShift-shiftxtotherightbyn,usingalogicalshift
*Canassumethat0<
=n<
=31
logicalShift(0x87654321,4)=0x08765432
20
3
*/
用算术右移实现逻辑右移功能
1、逻辑右移,高位补0。
2、不管是正数还是负数亦或是0,算术右移n位后位与&
一个前n位为0,后面的位都为1的数(0000…1111(n个0)),都能把移位后高位的符号变为0(如果原来为0就保持不变);
3.获得一个前位为0的数:
将(1<
31)得到0x80000000,算术右移n-1位,即((1<
31)>
n)<
1;
得到一个前n位为1,后32-n为0的数(1111…0000(n个1)),再按位取反~(((y<
1)得到一个前n位为0,后32-n为1的数(0000…1111(n个0)),再&
(x>
n)即可实现逻辑右移;
intlogicalShift(intx,intn){
inty=1;
return(~(((y<
1))&
n);
}
(4).bitCount函数,要求如下:
/*
*bitCount-returnscountofnumberof1'
sinword
bitCount(5)=2,bitCount(7)=3
40
4
返回32位数字串中1的个数;
1.依次检测x的每一位,ops会超出所给限操作符数;
2.类似,由于bitcount结果不会超过32,故可以利用一个32位二进制数
3.将每次的检测位数设定为4位的;
4.初始化tmp=0x1111,用来依次检测x>
i的0,8,16,24位是否为1;
5.利用val累加分别计算4个字节上1的个数,val的每个字节的值为对应
x每个字节上的1的个数;
6.最后将得到val四个字节的值相加,即x四个字节上1的个数的和,保留
最低字节的信息,为最后结果。
intbitCount(intx){
inttmp=(((0x01<
8|0x01)<
8|0x01;
intval=tmp&
x;
//检测x的0,8,16,24位是否为1
val+=tmp&
1);
//检测x的1,9,17,25位是否为1
2);
//...
3);
4);
5);
6);
7);
//检测x的7,15,23,31位是否为1
val+=(val>
16);
//将val的高16位加到低16位上
8);
//再将val的高8位加到低8位上
returnval&
0xff;
//保留val的最低byte信息为最终结果
(5).bang函数,要求如下:
*bang-Compute!
xwithoutusing!
bang(3)=0,bang(0)=1
12
4
不施用!
符号实现!
x的功能(即!
0=1,!
(othernumber)=1);
1.0的相反数仍为0。
2.其他整数的相反数符号位位必然与原数相反(原数和相反数必然符号位是其中1个为0,另一个为1);
3.一个不为0的数原数和相反数相或的结果符号位必然为1;
0原数和相反数相或的结果符号位必然为0;
4.将原数和相反数相或的结果的符号位移到最低位取反后&
上0x01就可以返回符号位的反(即相或的结果符号位为0则返回1,否则返回0);
5.一个数取相反数的规则跟负数补码规则一样,~x+1,按位取反加1即可;
intbang(intx){
inttmp=~x+1;
tmp=x|tmp;
tmp=tmp>
31;
return(~tmp&
0x01);
(6).tmin函数,要求如下:
*tmin-returnminimumtwo'
scomplementinteger
求补码编码的最小数;
补码编码的公式:
从公式可以可以看出当最高位为1,而其余位为0的时候,获得最小值。
我们要求的是32位的整数,所以最小值为0x80000000
简写就是0x01<
31,也就是1左移31位到最高位#代码:
inttmin(void)
{
return0x01<
31;
(7).fitsBits函数,要求如下:
*fitsBits-return1ifxcanberepresentedasan
*n-bit,two'
scomplementinteger.
*1<
=32
fitsBits(5,3)=0,fitsBits(-4,3)=1
15
求给定的一个数是否能用n位补码表示;
x的前32-n都为0或1,可以假定第n-1位为符号位,通过先算术左移再算术右移后比较与原数是否有差别;
有差别说明不能表示;
如果有差别,与原数亦或后不为0,否则为0,再用逻辑非!
取将有差别的返回0,无差别的返回1;
intfitsBits(intx,intn){
ints=32+(~n+1);
/*32+(~n+1)=32-n*/
return!
(x^((x<
s)>
s));
(8).divpwr2(除法)函数,要求如下:
*divpwr2-Computex/(2^n),for0<
=30
*Roundtowardzero
divpwr2(15,1)=7,divpwr2(-33,4)=-2
题目说明:
将一个数除以(2^n),有余数则往靠近0的方向取舍;
*分x为负数和非负数两种情况:
当x为非负数时,直接将x右移n位即可;
当x为负数时,如果x移出的位中不全为零,即有余数,则结果为右移n位后的结果加1;
intdivpwr2(intx,intn){
ints=!
!
31);
//取x的符号位的bool值
intt=(1<
n)+~0;
//t=(1<
n)-1(t=000...000111...111)
intlown=t&
//lown保存x的低n位的值
return(x>
n)+((!
lown)&
s);
(9).negate函数,要求如下:
*negate-return-x
negate
(1)=-1.
5
取一个数的相反数;
一个数的相反数正好就是对其每一位取反后加一,跟负数的补码规则相似,为~x+1,无论正负数都适用。
intnegate(intx)
return~x+1;
(10).isPositive函数,要求如下:
*isPositive-return1ifx>
0,return0otherwise
isPositive(-1)=0.
3
一个数为正数,则返回1,否则返回0;
1.正数的符号位为0,负数的符号位为1,如果是一个非0的数,返回符号位的反即可,
0单独考虑;
2.如果一个数x为0,则!
x=1,!
x=0;
否则,一个不为0的数!
x=0,!
x=1;
intisPositive(intx){
//x右移31位,得到符号位,若为正数,s=1
returns&
//返回x为正数满足的条件
(11).isLessOrEqual函数,要求如下:
*isLessOrEqual-ifx<
=ythenreturn1,elsereturn0
isLessOrEqual(4,5)=1.
24
如果x<
=y则返回1,否则返回0;
1.判断是否有x<
=y,即y-x>
=0是否成立,转化成判断y-x的正负;
分为同号和异号两种情况:
2.当x和y同号时,y-x不会发生溢出,判断y-x是否为非负数即可;
3.当x和y异号时,y-x可能会发生溢出,其结果一定和y(也就是!
x)的符号一致。
intisLessOrEqual(intx,inty){
intsx=!
//取x的符号位,为bool类型值
intsy=!
(y>
//取y的符号位,为bool类型值
intz=y+(~x+1);
//z=y-x,x求反加一得-x(-x绝对值不变)
(z>
//取z的符号位,为bool类型值
return(!
(sx^sy)&
s)|((sx^sy)&
sx);
//x,y同号;
x,y异号
(12).ilog2函数,要求如下:
*ilog2-returnfloor(logbase2ofx),wherex>
0
ilog2(16)=4
90
求一个数的log2的值;
*即求32位二进制x的最高位1对应的logbase2;
*由x>
0,ilog的结果不会超过31,可以想到用5位二进制来表示;
*依次折半累加得出最高位的权,方法如下(设结果ret=ijklm
(2)):
首先判断x的高16位是否全部为0,ret+=2^4*i,x相应右移16位;
再判断右移后x的高8位是否全部为0,ret+=2^3*j,x相应右移8位;
依次累加得出结果ret。
intilog2(intx){
ints,s1,s2,s3,s4,s5;
s=!
//判断最高位是否在高16位上
s1=s<
4;
//s1的权为2^4
x>
=s1;
//x相应右移
//判断最高位是否在高8位上
s2=s<
3;
//s1的权为2^3
=s2;
s3=s<
2;
=s3;
s4=s<
1;
=s4;
s5=s;
//最后一位
returns1+s2+s3+s4+s5;
//累加得出结果
(13).float_neg函数,要求如下:
*float_neg-Returnbit-levelequivalentofexpression-ffor
*floatingpointargumentf.
*Boththeargumentandresultarepassedasunsignedint'
s,but
*theyaretobeinterpretedasthebit-levelrepresentationsof
*single-precisionfloatingpointvalues.
*WhenargumentisNaN,returnargument.
Anyinteger/unsignedoperationsincl.||,&
&
.alsoif,while
10
将一个32位int型数解读为单精度浮点型数据f,返回-f;
1.若这个数被解读为特殊值(阶码位全1),则返回原数;
若为非特殊值,则直接对符号位(即最高位)取反;
2.使用异或操作符^。
对1求异或,等价于对1求反;
对0求异或,等价于保持原数;
当需要对一组数中一部分求反,一部分保持原数时,就可以使用异或运算;
3.判断一个浮点数是否为特殊值:
截取其阶码位和小数位与阶码位全1,小数位全0(即0x7fffffff)比较,若大于它,则必然为特殊值;
4.截取数据:
可以参考getByte,利用与运算&
,需要截取的数和1与,需要清零的数和0与,即可保留需要的数据部分
unsignedfloat_neg(unsigneduf){
unsignedresult,down;
down=uf&
(0x7fffffff);
if(down>
0x7f8fffff)
result=uf;
else
result=uf^0x80000000;
returnresult;
(14).float_i2f函数,要求如下:
*float_i2f-Returnbit-levelequivalentofexpression(float)x
*Resultisreturnedasunsignedint,but
*itistobeinterpretedasthebit-levelrepresentationofa
30
这个函数是将一个整形数,转化为浮点数,浮点数的符号只取决于第一位,所以对负数作取绝对值处理之后,所有数都可以按照同一种方法处理;
将二进制数左边的零位全部移出,直到移到“1”位为止,移出的位数shiftleft则为32位中前面“0”的个数,因此32-shiftleft代表的就是阶码的原码部分,再加上127的移码就可以得到最终的阶码;
移完0之后得到的aftershift这串数,就是小数部分,所以最后将aftershift右移9位,127+32-shiftleft左移23位,最前面加上符号位,即可得到转移后的数字;
unsignedfloat_i2f(intx){
unsignedshiftLeft=0;
unsignedafterShift,tmp,flag;
unsignedabsX=x;
unsignedsign=0;
//specialcase
if(x==0)return0;
//ifx<
0,sign=1000...,abs_x=-x
if(x<
0)
{
sign=0x80000000;
absX=-x;
}
afterShift=absX;
//countshift_leftandafter_shift
while
(1)
tmp=afterShift;
afterShift<
=1;
shiftLeft++;
if(tmp&
0x80000000)break;
if((afterShift&
0x01ff)>
0x0100)
flag=1;
elseif((afterShift&
0x03ff)==0x0300)
else
flag=0;
returnsign+(afterShift>
9)+((159-shiftLeft)<
23)+flag;
(14)float_twice函数,要求如下:
*float_twice-Returnbit-levelequivalentofexpression2*ffor
*theyaretobeinterpretedasthebit-levelrepresentationof
*WhenargumentisNaN,returnargument
将一个32位int型数解读为单精度浮点型数据f,返回2*f
*若这个数被解读为特殊值(阶码位全1),则返回原数;
若为非特殊值,如果是规格化数,则对阶码位作+1运算;
如果是非规格化数(阶码全为0),则对小数位作左移运算。
符号位不改变;
*这里涉及到将一个数据拆解为多个部分(符号位、阶码位和小数位),以及最后将各个部分拼合的运算;
对于拆分数据,如果只是保留需要的部分,其它位清零,那么只要作&
运算取数据即可;
如果只留下需要的部分,其它位剔除,那么要先作右移运算,再作类似&
0xFF的运算截断数据;
对于拼合数据,如果已经将几部分数据处理为置1位互不相干(即除了1有效位其它位都为0),那么直接用或|运算接合即可;
1.如果为特殊值,则返回uf本身;
2.如果为非规格化数,则进行左移(保留符号位,小数位仍为零)
3.如果为规格化数,则对符号位加一;
unsignedfloat_twice(unsigneduf){
unsignedresult,down;
(0x7f800000);
if(down==0x7f800000)
result=uf;
elseif(down==0)
result=((uf&
0x007fffff)<
1)|(uf&
0x80000000);
result=uf+0x00800000;
实验结果及分析:
如图,经过btest测试后运行结果全部正确,说明思路和代码都正确;
收获与体会:
通过本实验,我对各种数据类型的在计算机中的存储方式有了更深的了解,对计算机里面对数据的加减乘除的实质有了进一步认识,对移位操作更加熟悉和运用的更加灵活了,思维和代码能力都有了提高。
实
验成绩
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 报告