计算机系统基础之实验一报告【位操作&定/浮点数加减法&补码】

一、实验目的

加深对定点数补码、无符号数和IEEE754短浮点数标准的理解,加深对定点数和浮点数加减运算的理解。

二、实验原理

1.位操作
2.定点数补码表示
3.浮点数IEEE754表示

三、实验步骤

1、打开vm运行Ubuntu进入lab1-handout.tar所在目录开始实验操作
2、解压代码框架:tar -xvf lab1-handout.tar
3、进入解压后的目录make编译生成可执行文件,看看多了几个文件
4、通过修改bits.c 完成题目
5、做完题后进入vm进行make编译,注意提示信息,看编译是否出错
6、然后通过dlc测试(语法检查):./dlc bits.c (简单语法检查) ./dlc -e bits.c(检查操作运算符是否符合需求)
7、如果步骤6通过后,进行btest测试:./best (检查bits.c文件中所有函数功能,如果失败则给出测试用例)
8、修改答案,通过修改bits.c里的代码,继续进行步骤5、6、7

四、实验内容

1.代码及编程思路

(1)

  • lsbZero - set 0 to the least significant bit of x
  • Example: lsbZero(0x87654321) = 0x87654320
  • Legal ops: ! ~ & ^ | + << >>
  • Max ops: 5
  • Rating: 1

思路:x右移一位把最低有效位舍去,再左移把其余的数还原的原位上。

int lsbZero(int x) {
    x=x>>1;
    x=x<<1;
    return x;
}

(2)

  • TMax - return maximum two’s complement integer
  • Legal ops: ! ~ & ^ | + << >>
  • Max ops: 4
  • Rating: 1

思路:int最大值为0x7fffffff。最高位为0,其余为1,即10000000000000000000000000000000。再取反,即01111111111111111111111111111111,符号位为0,其余为1,是最大正整数。因此我们先创建一个最高位为1,其余0的数,然后对其取反。

int tmax(void) {
    return ~(1<<31);
}

(3)

  • isZero - returns 1 if x == 0, and 0 otherwise
  • Examples: isZero(5) = 0, isZero(0) = 1
  • Legal ops: ! ~ & ^ | + << >>
  • Max ops: 2
  • Rating: 1

思路:因为非零取非为0,0取非为1,直接 !x 即可。

int isZero(int x) {
    return !x;
}

(4)

  • isNegative - return 1 if x < 0, return 0 otherwise
  • Example: isNegative(-1) = 1.
  • Legal ops: ! ~ & ^ | + << >>
  • Max ops: 6
  • Rating: 2

思路:x<0即最高位为1移31为即为11111111111111111111111111111111(即为-1)取反+1即为1,x>0即最高位为0移31为即为00000000000000000000000000000000(即为0)取反+1为0。int型最高位为1时,这个数为负数。因此我们只要提取最高位的值即可。

int isNegative(int x) {
    return !!(x>>31);
}

(5)

  • sign - return 1 if positive, 0 if zero, and -1 if negative
  • Examples: sign(130) = 1
  •        sign(-23) = -1
    
  • Legal ops: ! ~ & ^ | + << >>
  • Max ops: 10
  • Rating: 2

思路:在isNegative的基础上区分正数和0.考虑运算 (!x)的结果。x位0时值为1,非零时值为0。那么 (!(!x))即!!x,运算在x为0时值为0,非零时值为1。这样就能区分0和正数了。也就是 “(负数确定)+(非负数确定)&(0确定)” 。

int sign(int x) {
    return  (x >> 0x1F) | !!x;
}

(6)

  • byteXor - compare the nth byte of x and y, if it is same, return 0, if not, return 1

  • example: byteXor(0x12345678, 0x87654321, 1) = 1

  •  	  byteXor(0x12345678, 0x87344321, 2) = 0
    
  • Legal ops: ! ~ & ^ | + << >>

  • Max ops: 20

  • Rating: 2

思路:一个字节相当于8个二进制位,通过右移操作并将结果与0xff即255进行与运算,即可取得这一字节的值。异或的特性是若两个数相等,则异或结果为0,利用这一特性即可得出答案。

int byteXor(int x, int y, int n) {
     int temp = ((x ^ y) >> (n << 3)) & 0xFF; 
     return !!temp;
}

(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

思路:shift=32-n。即先左移32-n位,在右移32-n位,即保留最后n位数。在与x异或,若两者相同表示x可被表示为一个n位整数,! 0为1。

int fitsBits(int x, int n) {
     int shift = (~n+1)+32;
     return !(x^((x<<shift)>>shift));
}

(8)

  • isEqual - return 1 if x == y, and 0 otherwise
  • Examples: isEqual(5,5) = 1, isEqual(4,5) = 0
  • Legal ops: ! ~ & ^ | + << >>
  • Max ops: 5
  • Rating: 2

思路:异或即可。具体:x和y相等那么(x^y)为0!为1即same,return 1;x和y不等那么(x^y)非0!为0 即if not,return 0。

int isEqual(int x, int y) {
    return !(x^y);
}

(9)

  • 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

思路:逻辑右移和算数右移在数为非负数的情况下是等价的。先考虑负数的情况。因为算数右移在负数情况下会将高位置1,先将符号位提出,移位后再将符号位补回,但操作后符号位可能失去原来的性质,要注意这一点的处理。

int logicalShift(int x, int n) {
    int offset = 0x1 << 31;
    int offsetValue = ~(offset >> n << 1);  
    return (x >> n) & offsetValue;
}

(10)

  • rempwr2 - Compute x%(2^n), for 0 <= n <= 30
  • Negative arguments should yield negative remainders
  • Examples: rempwr2(15,2) = 3, rempwr2(-35,3) = -3
  • Legal ops: ! ~ & ^ | + << >>
  • Max ops: 20
  • Rating: 3

思路:取模操作的实现:对于x<0来说:先用p算出除数的相反数,再用ans表示除数+余数,最后返回除数的相反数+除数+余数即可。对于x>=0来说:先用p算出除数的相反数,ans为x除以2^n的余数,最后返回ans即可。

int rempwr2(int x, int n) {
    int p = (~0) << n;
	  int ans = x & (~p);
	  return ans +   ( ( ( x & (~ans + 1) ) >> 0x1F ) & p );
}

(11)

  • isLess - if x < y then return 1, else return 0
  • Example: isLess(4,5) = 1.
  • Legal ops: ! ~ & ^ | + << >>
  • Max ops: 24
  • Rating: 3

思路:分两种情况: ①异号时,符号位为正的大。②同号时,两数相减,然后比较。可以避免计算溢出。

int isLess(int x, int y) {
    int not_y = ~y;
	return  ( ( ( ( x +  not_y + 1 ) & ( x ^ not_y ) ) | ( x & not_y ) )>> 0x1F ) & 1;
}

(12)

  • bitMask - Generate a mask consisting of all 1’s
  • lowbit and highbit
  • Examples: bitMask(5,3) = 0x38
  • Assume 0 <= lowbit <= 31, and 0 <= highbit <= 31
  • If lowbit > highbit, then mask should be all 0’s
  • Legal ops: ! ~ & ^ | + << >>
  • Max ops: 16
  • Rating: 3

思路:注意lowbit大于highbit的特判,利用异或特性。具体:当lowbit>highbit,& (i << lowbit)会直接覆盖得出的错误的数并置为0,((i << highbit) << 1) ^ (i << lowbit)中 (i << highbit) << 1为确定高位的数要取到 highbit+1才能保证在^运算中保留highbit ,低位也是如此,但不需要lowbit-1 ,进行^运算后即保留highbit到 lowbit为1,返回即可。

int bitMask(int highbit, int lowbit) {
    int i=~0;
	  return (((i << highbit) << 1) ^ (i << lowbit)) & (i << lowbit); 
}

(13)

  • 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

我不会

unsigned float_i2f(int x) {
    return 2;
}

(14)

  • logicalNeg - implement the ! operator, using all of
  •          the legal operators except !
    
  • Examples: logicalNeg(3) = 0, logicalNeg(0) = 1
  • Legal ops: ~ & ^ | + << >>
  • Max ops: 12
  • Rating: 4

思路:将X 和(-X)进行与运算。两相反数(非0)取反的&运算结果永远为0,0右移31位为0,0&1为0。0与0取反的&运算永远为-1,-1右移31位为-1,-1&1为1,显然:当且仅当X=0是结果的符号位为0。

int logicalNeg(int x) {
    return((~(~x+1)&~x)>>31)&1;
}

(15)

  • isPower2 - returns 1 if x is a power of 2, and 0 otherwise
  • Examples: isPower2(5) = 0, isPower2(8) = 1, isPower2(0) = 0
  • Note that no negative number is a power of 2.
  • Legal ops: ! ~ & ^ | + << >>
  • Max ops: 20
  • Rating: 4

思路:2^k必定大于0,首先排除负数和0的情况。运用lowbit位操作的方法计算 x&(-x)其结果为X的最低为1的位。如果结果正好等于X,则符合题意。

int isPower2(int x) {
    return !(((x&(~x+1))^x)|(!x)|(x>>31));
}

(16)

  • parityCheck - returns 1 if x contains an odd number of 1’s
  • Examples: parityCheck(5) = 0, parityCheck(7) = 1
  • Legal ops: ! ~ & ^ | + << >>
  • Max ops: 20
  • Rating: 4

思路:5步相互独立,每一步都为了寻找到能够消去1的移位,虽然有几步会增加1的数量,但1是对称,所以找到合适的移位数就可以一次性全部消去。因为1是偶数个x最终为0 ,并且要找偶数个1所以取32的一半,再一半……直到1为止。

int parityCheck(int x) {
   x = x ^ (x >> 16); 
   x = x ^ (x >> 8); 
   x = x ^ (x >> 4); 
   x = x ^ (x >> 2); 
   x = x ^ (x >> 1); 
   return x & 0x1; 
}

(17)

  • trueThreeFourths - multiplies by 3/4 rounding toward 0,
  • avoiding errors due to overflow
  • Examples: trueThreeFourths(11) = 8
  •         trueThreeFourths(-9) = -6
    
  •         trueThreeFourths(1073741824) = 805306368 (no overflow)
    
  • Legal ops: ! ~ & ^ | + << >>
  • Max ops: 20
  • Rating: 4

思路:首先通过右移一位和右移两位两个操作求得整数部分。然后判断小数部分以及是否是负数。

int trueThreeFourths(int x) {
    int y=x&0x3;
	  x=x>>2;
	  return (x<<1)+x+((y+y+y+((x>>0x1F)&0x3))>>2);
}

2.测试结果截图
在这里插入图片描述
在这里插入图片描述

五、实验总结

通过这次试验,我得知自己对位的相关操作的理解还不太到位,需要勤学多练,加深理解;部分函数理解不透彻,不能完整实现函数功能,可通过与他人交流、查阅资料得到处理。平时也可以通过自行进行习题演练,增强函数实现和优化方面的技能。除此之外,我更加深刻地了解数据与程序的机器级表示和处理,并加深了解数据类型的转换规则,能够在虚拟机的环境中通过两大测试优化函数功能,实现一些基础运算工程的功能。并且加深了和他人的交流,进一步提升了自学能力。

  • 12
    点赞
  • 77
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

米莱虾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值