中国海洋大学计算机基础实验报告

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

中国海洋大学计算机科学与技术系
实验报告
姓名:学号:专业:
科目:计算机系统原理题目:Lab1的实验
实验时间: 2019/11/09
实验成绩: 35/35 实验教师:
一、实验目的:
1更好地熟悉和掌握计算机中整数和浮点数的二进制编码表示。

2.实验中使用有限类型和数量的运算操作实现一组给定功能的函数,在此过程中加深对数据二进制编码表示的了解
3.熟悉linux基本操作命令,其中常用工具和程序开发环境
4.完善bits.c的各个函数,实现其功能,并通过.btest的测试
二、实验要求
1.尽快熟悉linux基本操作命令,还有其中常用工具和程序开发环境
2.除浮点数函数实现外,只能使用顺序程序结构,禁用if, do, while, for, switch等。

⏹有限操作类型,!~ & ^ | + << >> 各函数不一样
⏹禁用(!=、==、&&、|| 等组合操作符)
⏹常量值范围0~255
⏹禁用强制类型转换
⏹禁用整型外的任何其它数据类型
⏹禁用定义和宏
⏹不得使用函数
⏹具体要求可参看bits.c各函数框架的注释
⏹可以使用循环和条件控制;
⏹可以使用整型和无符号整型常量及变量(取值不受[0,255]限制);
⏹不使用任何浮点数据类型、操作及常量。

⏹可以使用int和unsigned两种整型数据
⏹禁用浮点数据类型、struct、union或数组结构。

⏹浮点数函数均使用unsigned型数据表示浮点数据。

⏹float_abs等函数必须能处理全范围的变量值,包括(NaN)和infinity。

三、实验内容(所修改函数代码,功能以及重要代码的解释):
主要操作内容:位操作函数; 补码运算函数; 浮点数表示函数
/*
* 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) { //right
x >>= 1;
x <<= 1;
return x;
}
/*
* byteNot - bit-inversion to byte n from word x
* Bytes numbered from 0 (LSB) to 3 (MSB)
* Examples: getByteNot(0x12345678,1) = 0x1234A978
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 6
* Rating: 2
*/
/*
功能:将指定第n个(这里的顺序从后面数起)字节(8位)与1异或*/
int byteNot(int x, int n) { //right
int y = 0xff;//先预定一个8位的11111111
n <<= 3;//将n*8,为了后续字节的移动
y <<= n;//将这8个1移动到n所指的字节
x = x^y;
return x;
}
/*
* 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
*/
/*
判断x与y第n个字节是否相同
*/
int byteXor(int x, int y, int n) { //right
n <<= 3;
x >>= n;
y >>= n;
x = x&(0xff);
y = y&(0xff);
return !!(x^y);//这里的两个!!是为了让(x^y)的结果为0或1,而不是一个具体的数,例如:!!
8 = 1
}
/*
* logicalAnd - x && y
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 20
* Rating: 3
*/
/*
实现逻辑与
*/
int logicalAnd(int x, int y) { //right
x = !x|!y;//只要x和y中有一个0,x就是1
return !x;//为了符合要求取反
}
/*
* logicalOr - x || y
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 20
* Rating: 3
*/
/*
实现逻辑或
*/
int logicalOr(int x, int y) { //right
x = x | y;
return !!x;//让x规范输出
}
/*
* rotateLeft - Rotate x to the left by n
* Can assume that 0 <= n <= 31
* Examples: rotateLeft(0x87654321,4) = 0x76543218
* Legal ops: ~ & ^ | + << >> !
* Max ops: 25
* Rating: 3
*/
/*
将x的前n位移动到后面去
*/
int rotateLeft(int x, int n) { //right
int toZero = ~(((1<<31)>>31)<<n); //获得11.........000(32-n个1,n个0)x = ((x>>(32+(~n+1)))&toZero) + (x<<n);//(32+(~n+1))的意思是32-n; return x;
}
/*
* 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
*/
/*
判断这个2进制数是否为奇数个1
*/
int parityCheck(int x) {
/*
这个方法的思想就是
先让后16位和前16位来比较
相同位置的1异或后会变成0
也就是偶数个1会被削掉一部分
然后保存到前16位(后面的16位不用管了)
然后用前16位中的后8位与前8位比较
以此类推
*/
int y = x<<16;
y = y^x;
y = y^(y<<8);
y = y^(y<<4);
y = y^(y<<2);
y = y^(y<<1);
y >>= 31;
y = y&1;
return y;
}
/*
* mul2OK - Determine if can compute 2*x without overflow
* Examples: mul2OK(0x30000000) = 1
* mul2OK(0x40000000) = 0
*
* Legal ops: ~ & ^ | + << >>
* Max ops: 20
* Rating: 2
*/
/*判断这个2进制数乘以2后会不会溢出
*/
int mul2OK(int x) { //right
/*这个方法的思想就是
发现了一个规律:只要这个2进制数前两位不一样就会溢出*/
int f = ~((1<<31)>>30);
int a = (x >> 31)&f;//the first
int b = (x >> 30)&f;//the second
int c = (~(a^b)&f);
return c;
}
/*
* mult3div2 - multiplies by 3/2 rounding toward 0,
* Should exactly duplicate effect of C expression (x*3/2),
* including overflow behavior.
* Examples: mult3div2(11) = 16
* mult3div2(-9) = -13
* mult3div2(1073741824) = -536870912(overflow)
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 12
* Rating: 2
*/
/*
乘以2/3
*/
int mult3div2(int x) { //right
/*注意,这里的顺序不能变,只能先乘以3,再除以2,因为关系到溢出的判断*/ x = (x << 1) + x;//乘以3等价于,这个数乘以2加上他本身
x += (x >> 31)&(~((1<<31)>>30));//如果x是负数,则x在除以2时要加上一个偏移量x >>= 1;
return x;
}
/*
* subOK - Determine if can compute x-y without overflow
* Example: subOK(0x80000000,0x80000000) = 1,
* subOK(0x80000000,0x70000000) = 0,
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 20
* Rating: 3
*/
/*
判断x-y后会不会溢出
*/
int subOK(int x, int y) {
int z = x + ~y + 1;//x - y
int f = ~((1<<31)>>30);//获取数0000 (001)
//获取他们的符号位
x = (x>>31)&f;
y = (y>>31)&f;
z = (z>>31)&f;
//发现规律,x与y和z的符号位不同时会溢出
//意思就是正数减去负数为负数就是溢出
//负数减去正数为正数就是溢出
return !((x^y)&(x^z));
}
/*
* absVal - absolute value of x
* Example: absVal(-1) = 1.
* You may assume -TMax <= x <= TMax
* Legal ops: ! ~ & ^ | + << >>
* Max ops: 10
* Rating: 4
*/
/*
取x的绝对值
*/
int absVal(int x) { //right
int y = x >> 31;//符号位,得到的y只能是全为1或全为0。

x = (y&(~x+1)) + (~y&x);//当y全是1时,加法后面就是0,反之。

return x;
}
/*
* float_abs - Return bit-level equivalent of absolute value of 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
*/
/*
返回uf的绝对值,如果uf是个NAN就返回原值
*/
unsigned float_abs(unsigned uf) {
//浮点数的储存方式没有用到补码,于是直接去符号即可
int x = (uf&0x7fffffff);
//当阶码都是1,而.f不为0,根据定义,这个数就是NAN
if(x > 0x7f800000) {
return uf;
}
else {
return x;
}
}
/*
* float_f2i - Return bit-level equivalent of expression (int) f
* for floating point argument f.
* Argument is passed as unsigned int, but
* it is to be interpreted as the bit-level representation of a
* single-precision floating point value.
* Anything out of range (including NaN and infinity) should return
* 0x80000000u.
* Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while
* Max ops: 30
* Rating: 4
*/
/*
将uf中的数转换为int型,当uf为NAN或无穷大或uf越界时返回0x80000000
*/
int float_f2i(unsigned uf) {
int b = (uf>>31);//符号位
int x = (uf&(0x7f800000));//阶码
int x1 = x;
int y = (uf&(0x007fffff));//尾数
x >>= 23;//将阶码右移23位,得到e
x1 = x-127;//获得指数e-127
if(((uf&0x7fffffff) >= 0x7f800000) || x1 > 30)//后面的x>30是因为int只有32位,会越界return 0x80000000;
if(x < 127)//指数小于0,代表它一定是个小数,则直接返回0
return 0;
if(x1 > 23){//因为尾数只有23位,如果指数大于23则y中的尾数左移x1-23位
y <<= x1 - 23;
y += (1 << x1);//将1加进去(因为开始是1.y)
}else{
y >>= (23 + (~x1 + 1));//如果指数小于23,则尾数右移23-x1位,意思就是舍去小数部分
y += (1 << x1);//将1加进去(因为开始是1.y)
}
b = (b<<31)>>31;//对符号位移动,让b全变为1或0
y = (b&(~y+1)) + ((~b)&y);//添加y的符号位(当b全是1时,加法后面就是0,反之。

)return y;
}}
四、实验结果(在虚拟机中,进行语法检查,编译,正确性检查的截图):
五、实验总结
通过本次实验,让我掌握的计算机的基本原理,懂得了一系列2进制数的操作,以及学会了在linux系统下操作的一些常用命令,帮助我更加深入的理解c语言的底层知识。

相关文档
最新文档