1.更好地熟悉和掌握计算机中整数和浮点数的二进制编码表示。
2. 加深对数据二进制编码表示的了解。
3. 使用有限类型和数量的运算操作实现一组给定功能的函数。
二、实验仪器设备/实验环境1.Linux操作系统—64位 Ubuntu 18.04
2. C编译环境(gcc)
3. 计算机
三、实验内容本实验每位学生拿到一个datalab-handout.tar文件。学生可以通过U盘、网盘、虚拟机共享文件等方式将其导入到Ubuntu实验环境中,选择合适位置存放。然后在Ubuntu环境下解压(tar -xvf …)。解压后,根据文件中的叙述和要求更改bits.c文件,其他文件不要动。本次实验的主要操作方式为:使用C语言的位操作符实现题目要求。
实验步骤:1. 使用dlc检查函数实现代码是否符合实验要求的编码规则。
首先是将压缩包拖进虚拟机,将压缩包解压,然后编辑bits.c 代码在最后面附上。
cd....进入文件夹,输入./dlc bits.c检测是否有错误,如下图:
输入: ./dlc -e bits.c 无问题情况如下图:
以下是有问题:
2、使用 btest 检查函数实现代码的功能正确性。
a) 首先使用make编译生成btest可执行程序,部分warning不需要特殊处理,但如果出现的warning过多则需要适当注意是否程序中有错误。(以下是正确的情况)
如果输入make报下面错的话:(可能是没有gcc编辑环境)
安装gcc环境:
sudo apt update 先更新
sudo apt install build-essential
gcc --version 查看gcc版本
sudo apt-get install gcc-multilib
(输入以上命令应该就可以了)
b) 然后调用 btest 命令检查 bits.c中所有函数的功能正确性。
(完美收工,快去做实验吧!!冲冲冲)
bits.c代码:
#if 0
You will provide your solution to the Data Lab by
editing the collection of functions in this source file.
INTEGER CODING RULES:
Replace the "return" statement in each function with one
or more lines of C code that implements the function. Your code
must conform to the following style:
int Funct(arg1, arg2, ...) {
int var1 = Expr1;
...
int varM = ExprM;
varJ = ExprJ;
...
varN = ExprN;
return ExprR;
}
Each "Expr" is an expression using onLY the following:
1. Integer constants 0 through 255 (0xFF), inclusive. You are
not allowed to use big constants such as 0xffffffff.
2. Function arguments and local variables (no global variables).
3. Unary integer operations ! ~
4. Binary integer operations & ^ | + << >>
Some of the problems restrict the set of allowed operators even further.
Each "Expr" may consist of multiple operators. You are not restricted to
one operator per line.
You are expressly forbidden to:
1. Use any control constructs such as if, do, while, for, switch, etc.
2. Define or use any macros.
3. Define any additional functions in this file.
4. Call any functions.
5. Use any other operations, such as &&, ||, -, or ?:
6. Use any form of casting.
7. Use any data type other than int. This implies that you
cannot use arrays, structs, or unions.
You may assume that your machine:
1. Uses 2s complement, 32-bit representations of integers.
2. Performs right shifts arithmetically.
3. Has unpredictable behavior when shifting if the shift amount
is less than 0 or greater than 31.
EXAMPLES OF ACCEPTABLE CODING STYLE:
int pow2plus1(int x) {
return (1 << x) + 1;
}
int pow2plus4(int x) {
int result = (1 << x);
result += 4;
return result;
}
FLOATING POINT CODING RULES
For the problems that require you to implement floating-point operations,
the coding rules are less strict. You are allowed to use looping and
conditional control. You are allowed to use both ints and unsigneds.
You can use arbitrary integer and unsigned constants. You can use any arithmetic,
logical, or comparison operations on int or unsigned data.
You are expressly forbidden to:
1. Define or use any macros.
2. Define any additional functions in this file.
3. Call any functions.
4. Use any form of casting.
5. Use any data type other than int or unsigned. This means that you
cannot use arrays, structs, or unions.
6. Use any floating point data types, operations, or constants.
NOTES:
1. Use the dlc (data lab checker) compiler (described in the handout) to
check the legality of your solutions.
2. Each function has a maximum number of operations (integer, logical,
or comparison) that you are allowed to use for your implementation
of the function. The max operator count is checked by dlc.
Note that assignment ('=') is not counted; you may use as many of
these as you want without penalty.
3. Use the btest test harness to check your functions for correctness.
4. Use the BDD checker to formally verify your functions
5. The maximum number of ops for each function is given in the
header comment for each function. If there are any inconsistencies
between the maximum ops in the writeup and in this file, consider
this file the authoritative source.
#endif
int isZero(int x) {
return !x;
}
int negate(int x) {
return ~x+1;
}
int specialBits(void) {
return ~(0xD7<<14);
}
int upperBits(int n) {
int a = 1 << 31;
int b = n + (~0);
int k = ((!!n) << 31) >> 31;
return k & (a >> b);
}
int bitMatch(int x, int y) {
return (~(x&~y))&(~(~x&y));
}
int bitOr(int x, int y) {
return ~(~x&~y);
}
int absVal(int x) {
return (x^(x>>31))+((x>>31)&1);
}
int logicalNeg(int x) {
return ~(x|(~x+1))>>31&1;
}
int bitParity(int x) {
x^=x>>16;
x^=x>>8;
x^=x>>4;
x^=x>>2;
x^=x>>1;
return x&1;
}
int byteSwap(int x, int n, int m) {
int m_n = 0xff << (n<<3);
int m_m = 0xff << (m<<3);
int _n = ((x&m_n)>>(n<<3))&0xff;
int _m = ((x&m_m)>>(m<<3))&0xff;
return (x&~m_m&~m_n)|(_n<<(m<<3))|(_m<<(n<<3));
}
int getByte(int x, int n) {
return (x>>(n<<3))&0xff;
}
int isGreater(int x, int y) {
int sign_ = ((~x&y)>>31)&1;
int mark_ = ~((x^y)>>31);
int equl_ = !!(x^y);
return sign_ | ((mark_)&(~(x+~y+1))>>31&equl_);
}
int isNegative(int x) {
return ((x>>31)&1);
}
int isPower2(int x) {
int ret = ((!(x&(x+~0))) & ((~(x>>31)&(!!x))));
return ret;
}
int addOK(int x, int y) {
return (((x^y)>>31)|~(((x+y)^x)>>31))&1;
}
int subtractionOK(int x, int y) {
int z ;
int m = y ;
y=(~y)+1 ;
z=x+y ;
z=(z^x)&(m^x) ;
return !((z>>31)&1) ;
}
int oddBits(void) {
int x = 0xaa;
x |= x<<8;
x |= x<<16;
return x;
}
int replaceByte(int x, int n, int c) {
int mask_ = 0xff << (n<<3);
c <<= (n<<3);
return (x&(~mask_))|c;
}
int rotateLeft(int x, int n) {
int mask = (~0) + (1<
return ((x<
unsigned floatAbsVal(unsigned uf) {
if((uf&0x7f800000)>>23 == 255 && uf<<9 != 0) return uf;
return uf & 0x7fffffff;
}
int floatIsEqual(unsigned uf, unsigned ug) {
if(!(uf&0x7fffffff) && !(ug&0x7fffffff)) return 1;
if((uf&0x7fffffff) > 0x7f800000) return 0;
if((ug&0x7fffffff) > 0x7f800000) return 0;
return uf == ug;
}



