LAB2--datalab--(包括如何在虚拟机中共享文件)

 实验题目:LAB2-datalab

实验目的:填写bits.c文件中尚未完成的各个函数的内容,但是,本实验要求只使用有限数量、规定的操作符。

实验环境:个人电脑、linux发行版本

实验内容及操作步骤:

  • 共享文件

步骤:

1.在虚拟机内添加路径:进入虚拟机软件,点开工具栏上方虚拟机,点击设置,选择选项,查看共享文件夹,点击添加,下一步

2.在主机路径中点击浏览,然后将主机中要共享的文件夹添加到目录下。

3.点击启用此共享,完成。

4.在虚拟机中找到munu文件夹,进入,即可找到共享的文件夹。然后将文件夹剪切至桌面即可使用。

二、填写函数

1.bitAnd - x&y using only ~ and |

    Example: bitAnd(6, 5) = 4

    Legal ops: ~ |

   Max ops: 8

    Rating: 1

函数内容:

函数讲解:这个函数是想用~|完成两数字相与,这个利用德摩根对偶律即可

2.getByte - Extract byte n from word x

 *   Bytes numbered from 0 (LSB) to 3 (MSB)

 *   Examples: getByte(0x12345678,1) = 0x56

 *   Legal ops: ! ~ & ^ | + << >>

 *   Max ops: 6

 *   Rating: 2

函数内容:

函数讲解:这有个32位的数字,但是他是16进制的,从低位0开始,一字节一字节的数,数到需要的n就输出这个位置(这个位置不是指比特位)对应一字节的数字。这个的思路就是先算移动的位数(比特位),是n*2^3个位,(这里左移一位就是移动了1*2^3个位数,左移两位就是2*2^3个位数)然后x左移相应位数,再跟0xff相与得到这个字节的数字。

3.logicalShift - shift x to the right by n, using a logical shift

 *   Can assume that 0 <= n <= 31

 *   Examples: logicalShift(0x87654321,4) = 0x08765432

 *   Legal ops: ! ~ & ^ | + << >>

 *   Max ops: 20

 *   Rating: 3

函数内容:

函数讲解:

该函数是需要逻辑移位,右移n个比特位后输出相对应的数字。因为这个“>>”是算术移位而不是逻辑移位,所以要考虑将前面补的1全部变成0,那么就需要和前面都是0的一个数字相与,这里是先将1直接移到最左边,接着右移n位(此时高n+1位都是1),再左移1位(此时高n位都是1,后32-n位为0)再将其取反,得到的是我们要的前n位为0,后32-n位为1,与右移后的x相与即可。

4.bitCount - returns count of number of 1's in word

 *   Examples: bitCount(5) = 2, bitCount(7) = 3

 *   Legal ops: ! ~ & ^ | + << >>

 *   Max ops: 40

 *   Rating: 4

函数内容:

函数讲解:本函数用了二分法,先统计两个数字中1的个数,再统计四个数字中1的个数,以此类推。

5.bang - Compute !x without using !

 *   Examples: bang(3) = 0, bang(0) = 1

 *   Legal ops: ~ & ^ | + << >>

 *   Max ops: 12

 *   Rating: 4

函数内容:

函数讲解:这个函数就是要用~ & ^ | + << >>来替换!,从而达到!的效果。这里我们知道!是取非得意思,任何一个非零数在!后都会变成0(在c中非零数即为true,0为false),0在!之后会变成1。这里我的思路是,如果是非零的数字或上他的相反数,那么最高位一定是1,因为这里是算数移位,所以右移会补齐符号位的数字,所以这里需要把结果取反,这样最高位就一定是0,然后再将最高位算数右移到最后一位,那么我们就可以得到全为0的一个32位二进制数,只需把它和1相与即可得到0这个结果。如果是0,32位的0或上他的相反数-0还是0,取反后为1111...111,同理可得1这个结果,这样就完成了任务。

6.tmin - return minimum two's complement integer

 *   Legal ops: ! ~ & ^ | + << >>

 *   Max ops: 4

 *   Rating: 1

函数内容:

函数讲解:我们可以知道这里是int类型,那么二进制中有正负之分,最小的二进制就应该是-2147483648,正数的2147483648是第31位是1,32位符号位是0。那么他的补码就是取反+1,即把1左移31位即可得到-2147483648.

7.fitsBits - return 1 if x can be represented as an

 *  n-bit, two's complement integer.

 *   1 <= n <= 32

 *   Examples: fitsBits(5,3) = 0, fitsBits(-4,3) = 1

 *   Legal ops: ! ~ & ^ | + << >>

 *   Max ops: 15

 *   Rating: 2

函数内容:

函数讲解:这个函数是让我们判断,如果x可以被表示成n位二进制就返回1,不能就返回0.这道题其实是让我们判断x是否在-2^(n-1)至2^(n-1)-1之间,如果在那么返回1,不在就返回0。如果这里在这个范围内,那么将它移(n-1)位后,再+1最后移位的结果就为0,最后取反结果为1.如果不在这个范围内,移位的结果就是1,最后取反结果为0.

 

8.divpwr2 - Compute x/(2^n), for 0 <= n <= 30

 *  Round toward zero

 *   Examples: divpwr2(15,1) = 7, divpwr2(-33,4) = -2

 *   Legal ops: ! ~ & ^ | + << >>

 *   Max ops: 15

 *   Rating: 2

函数内容:

函数讲解:

这个函数是让我们计算 x/(2^n)的值,因为这里会四舍五入,如果是正数,下取整,负数则上取整。但是这里的负数不对,所以这道题主要处理负数的上取整情况。这里选择把负数加一个偏移量“((1<<n)+(~0))”来做到向上取整。这里的x>>31是将负数的符号位移到最后,这样和偏移量相与就得到偏移量,然后负数再加上偏移量就可以进行正确结果的除法。

9.negate - return -x

 *   Example: negate(1) = -1.

 *   Legal ops: ! ~ & ^ | + << >>

 *   Max ops: 5

 *   Rating: 2

函数内容:

函数讲解:这个函数是要返回一个数的相反数。我们可以知道如果要返回一个数的相反数,那么就让他按位取反+1即可得到。

10.isPositive - return 1 if x > 0, return 0 otherwise

 *   Example: isPositive(-1) = 0.

 *   Legal ops: ! ~ & ^ | + << >>

 *   Max ops: 8

 *   Rating: 3

函数内容:

函数讲解:

这个函数是让我们判断,如果一个数是正数,那么返回1,如果是负数或者0那么返回0.我们可以知道机器中二进制都是补码的形式。补码最高位是符号位,那么我们只需要将符号位移到最后,再把结果!就可以得到。但是这里需要考虑0的问题,如果是0的话按题意需要返回0,那么我们就需要和1相或,我们可以知道0或任何数都等于它本身,1或任何数都为1.这里除0以外的数都是和0相或,所以是它本身,再进行!操作即可输出正确结果,而0需要和1相或,然后再!即可输出正确结果。

11.isLessOrEqual - if x <= y  then return 1, else return 0

 *   Example: isLessOrEqual(4,5) = 1.

 *   Legal ops: ! ~ & ^ | + << >>

 *   Max ops: 24

 *   Rating: 3

函数内容:

函数讲解:

这个函数就是让我们比较x和y的大小,如果x<=y,那么返回1,否则返回0.这里signx是x的符号位,signy是y的符号位,“!(signx^signy)”是异或非,相同为1,不同为0。1和任何数相与都是它本身,0和任何数相与都是0.也就是说这里的signSame先判断x和y的符号位是否相等,如果相等,那么再判断x和y的大小关系,看x+(~y)>>31位的结果,这个x+(~y)其实就是x-y-1。然后判断结果的符号位是正还是负。这里我们来看,如果x是负数,y是正数,那么signDiffer为1,最后返回1,正确。如果x是正数,y是负数,那么signDiffer为0,signSame为0,返回0,正确。如果x是正数y也是正数,那么signDiffer是0,signSame是根据x和y的大小关系来的,负数同理。这里的signDiffer的作用是判断x和y一正一负的情况。

 

12.ilog2 - return floor(log base 2 of x), where x > 0

 *   Example: ilog2(16) = 4

 *   Legal ops: ! ~ & ^ | + << >>

 *   Max ops: 90

 *   Rating: 4

函数内容:

函数讲解:实现计算,同样采用分治法,我们先将32位长度处理为16位长度,(!!(x>>16))<<4实现了当x大于2^16时,先将16记录下来(1<<4),否则这一步就是0,之后bitsNumber+((!!(x>>(bitsNumber+8)))<<3),当x大于16时,记录下来的bitsNumber同样再加上去掉后16+8位之后的数字,这样对前一半16位再进行处理,依次循环下去,否则当bitsNumber小于16时,处理的是后16位的后8位,依次类推,得到最终结果。

 

13.float_neg - Return bit-level equivalent of expression -f for

 *   floating point argument f.

 *   Both the argument and result are passed as unsigned int's, but

 *   they are to be interpreted as the bit-level representations of

 *   single-precision floating point values.

 *   When argument is NaN, return argument.

 *   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while

 *   Max ops: 10

 *   Rating: 2

函数内容:

函数讲解:这个函数是让我们求浮点数的相反数。对于单精度浮点数,NaN 表示为指数为 emax + 1 = 128(阶码全为 1),且尾数域不等于零的浮点数,这里0x7f800000就是NaN。那么直接将符号位改反即可得到浮点数的相反数,这里让uf与0x80000000异或,这样就能将符号位取反。当uf为NAN时,直接返回uf就好,所以要加上一步判断。这里不是很清楚为什么要出现tmp,也将tmp注释,但是不是满分,这里很费解。

14.float_i2f - Return bit-level equivalent of expression (float) x

 *   Result is returned as unsigned int, but

 *   it is to be interpreted as the bit-level representation of a

 *   single-precision floating point values.

 *   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while

 *   Max ops: 30

 *   Rating: 4

函数内容:

函数讲解:将整形转化为无符号单精度浮点数,事实上整个过程就是一个求浮点数的过程。我们先取得符号位即sign,由于后面不需要对符号进行处理,所以将剩余部分全部取为正数形式,即absX,这样得到的就是无符号的数值,接着将有数字的部分直接移动到最高位,记录移动的位数。然后接下来的if代码没看懂是什么意思。他的159是什么含义也不清楚。

15.float_twice - Return bit-level equivalent of expression 2*f for

 *   floating point argument f.

 *   Both the argument and result are passed as unsigned int's, but

 *   they are to be interpreted as the bit-level representation of

 *   single-precision floating point values.

 *   When argument is NaN, return argument

 *   Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while

 *   Max ops: 30

 *   Rating: 4

函数内容:

函数讲解:这个函数是将无符号浮点数乘2。这里先要判断他的exp的情况,如果exp全为1,那么他是特殊值,即NaN,直接返回就行。如果exp全0,那么他表示的数就是非规格化形式,对于非规格化数,查表我们可以总结出来,对其尾部乘2,即直接左移1位,即可完成浮点数乘2。对于exp不全为0页不全为1的规格化数,直接对其阶码+1即可。

 

 

实验结果及分析:

1.首先使用dlc检查函数的正确性,如果没有任何反应这说明函数编写符合要求。

然后输入./dlc -e bits.c检查每一个函数的操作数,皆符合要求。

2.其次用btest来测试函数。这里需要注意的是btest在使用前一定要先make btest。包括如果更新了函数,也一定要make btest。这里我们可以看到最终结果是41分满分。

实验感想:这个还是建议先看书,第二章,理解了机器代码再进行实验会好很多。而且对后面的考试和理解计算机系统都是会有好处的。我的代码也是参考了很多大神的,可以说是没有自己写的,之后还会反复打磨这些代码,先看书吧。有什么问题也欢迎大神在下方评论指出。

  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值