一、实验目的
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代码:
/*? ?* CS:APP Data Lab? ?*? ?* <Please put your name and userid here> ?*? ?* bits.c - Source file with your solutions to the Lab. ?* ? ? ? ? ?This is the file you will hand in to your instructor. ?* ?* WARNING: Do not include the <stdio.h> header; it confuses the dlc ?* compiler. You can still use printf for debugging without including ?* <stdio.h>, although you might get a compiler warning. In general, ?* it's not good practice to ignore compiler warnings, but in this ?* case it's OK. ? ?*/
#if 0 /* ?* Instructions to Students: ?* ?* STEP 1: Read the following instructions carefully. ?*/
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, ...) { ? ? ? /* brief description of how your implementation works */ ? ? ? 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: ? /* ? ?* pow2plus1 - returns 2^x + 1, where 0 <= x <= 31 ? ?*/ ? int pow2plus1(int x) { ? ? ?/* exploit ability of shifts to compute powers of 2 */ ? ? ?return (1 << x) + 1; ? }
? /* ? ?* pow2plus4 - returns 2^x + 4, where 0 <= x <= 31 ? ?*/ ? int pow2plus4(int x) { ? ? ?/* exploit ability of shifts to compute powers of 2 */ ? ? ?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.
/* ?* STEP 2: Modify the following functions according the coding rules. ?*? ?* ? IMPORTANT. TO AVOID GRADING SURPRISES: ?* ? 1. Use the dlc compiler to check that your solutions conform ?* ? ? ?to the coding rules. ?* ? 2. Use the BDD checker to formally verify that your solutions produce? ?* ? ? ?the correct answers. ?*/
#endif /* Copyright (C) 1991-2018 Free Software Foundation, Inc. ? ?This file is part of the GNU C Library.
? ?The GNU C Library is free software; you can redistribute it and/or ? ?modify it under the terms of the GNU Lesser General Public ? ?License as published by the Free Software Foundation; either ? ?version 2.1 of the License, or (at your option) any later version.
? ?The GNU C Library is distributed in the hope that it will be useful, ? ?but WITHOUT ANY WARRANTY; without even the implied warranty of ? ?MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ?See the GNU ? ?Lesser General Public License for more details.
? ?You should have received a copy of the GNU Lesser General Public ? ?License along with the GNU C Library; if not, see ? ?<http://www.gnu.org/licenses/>. ?*/ /* This header is separate from features.h so that the compiler can ? ?include it implicitly at the start of every compilation. ?It must ? ?not itself include <features.h> or any other header that includes ? ?<features.h> because the implicit include comes before any feature ? ?test macros that may be defined in a source file before it first ? ?explicitly includes a system header. ?GCC knows the name of this ? ?header in order to preinclude it. ?*/ /* glibc's intent is to support the IEC 559 math functionality, real ? ?and complex. ?If the GCC (4.9 and later) predefined macros ? ?specifying compiler intent are available, use them to determine ? ?whether the overall intent is to support these features; otherwise, ? ?presume an older compiler has intent to support these features and ? ?define these macros by default. ?*/ /* wchar_t uses Unicode 10.0.0. ?Version 10.0 of the Unicode Standard is ? ?synchronized with ISO/IEC 10646:2017, fifth edition, plus ? ?the following additions from Amendment 1 to the fifth edition: ? ?- 56 emoji characters ? ?- 285 hentaigana ? ?- 3 additional Zanabazar Square characters */ /* We do not support C11 <threads.h>. ?*/ /* ?* isZero - returns 1 if x == 0, and 0 otherwise? ?* ? Examples: isZero(5) = 0, isZero(0) = 1 ?* ? Legal ops: ! ~ & ^ | + << >> ?* ? Max ops: 2 ?* ? Rating: 1 ?*/ int isZero(int x) { ? return !x; } /*? ?* negate - return -x? ?* ? Example: negate(1) = -1. ?* ? Legal ops: ! ~ & ^ | + << >> ?* ? Max ops: 5 ?* ? Rating: 2 ?*/ int negate(int x) { ? return ~x+1; } /*? ?* specialBits - return bit pattern 0xffca3fff ?* ? Legal ops: ! ~ & ^ | + << >> ?* ? Max ops: 3 ?* ? Rating: 1 ?*/ int specialBits(void) { ? ? return ~(0xD7<<14); } /*? ?* upperBits - pads n upper bits with 1's ?* ?You may assume 0 <= n <= 32 ?* ?Example: upperBits(4) = 0xF0000000 ?* ?Legal ops: ! ~ & ^ | + << >> ?* ?Max ops: 10 ?* ?Rating: 1 ?*/ int upperBits(int n) { ? int a = 1 << 31; ? int b = n + (~0); ? int k = ((!!n) << 31) >> 31; ? return k & (a >> b); } /*? ?* bitMatch - Create mask indicating which bits in x match those in y ?* ? ? ? ? ? ?using only ~ and &? ?* ? Example: bitMatch(0x7, 0xE) = 0x6 ?* ? Legal ops: ~ & | ?* ? Max ops: 14 ?* ? Rating: 1 ?*/ int bitMatch(int x, int y) { ? return (~(x&~y))&(~(~x&y)); } /*? ?* bitOr - x|y using only ~ and &? ?* ? Example: bitOr(6, 5) = 7 ?* ? Legal ops: ~ & ?* ? Max ops: 8 ?* ? Rating: 1 ?*/ int bitOr(int x, int y) { ? return ~(~x&~y); } /*? ?* absVal - absolute value of x ?* ? Example: absVal(-1) = 1. ?* ? You may assume -TMax <= x <= TMax ?* ? Legal ops: ! ~ & ^ | + << >> ?* ? Max ops: 10 ?* ? Rating: 4 ?*/ int absVal(int x) { ? return (x^(x>>31))+((x>>31)&1); } /*? ?* 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? ?*/ int logicalNeg(int x) { ? return ~(x|(~x+1))>>31&1; } /* ?* bitParity - returns 1 if x contains an odd number of 0's ?* ? Examples: bitParity(5) = 0, bitParity(7) = 1 ?* ? Legal ops: ! ~ & ^ | + << >> ?* ? Max ops: 20 ?* ? Rating: 4 ?*/ int bitParity(int x) { ? x^=x>>16; ? x^=x>>8; ? x^=x>>4; ? x^=x>>2; ? x^=x>>1; ? return x&1; } /*? ?* byteSwap - swaps the nth byte and the mth byte ?* ?Examples: byteSwap(0x12345678, 1, 3) = 0x56341278 ?* ? ? ? ? ? ?byteSwap(0xDEADBEEF, 0, 2) = 0xDEEFBEAD ?* ?You may assume that 0 <= n <= 3, 0 <= m <= 3 ?* ?Legal ops: ! ~ & ^ | + << >> ?* ?Max ops: 25 ?* ?Rating: 2 ?*/ 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)); } /*? ?* getByte - Extract byte n from word x ?* ? Bytes numbered from 0 (least significant) to 3 (most significant) ?* ? Examples: getByte(0x12345678,1) = 0x56 ?* ? Legal ops: ! ~ & ^ | + << >> ?* ? Max ops: 6 ?* ? Rating: 2 ?*/ int getByte(int x, int n) { ? return (x>>(n<<3))&0xff; } /*? ?* isGreater - if x > y ?then return 1, else return 0? ?* ? Example: isGreater(4,5) = 0, isGreater(5,4) = 1 ?* ? Legal ops: ! ~ & ^ | + << >> ?* ? Max ops: 24 ?* ? Rating: 3 ?*/ 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_); } /*? ?* isNegative - return 1 if x < 0, return 0 otherwise? ?* ? Example: isNegative(-1) = 1. ?* ? Legal ops: ! ~ & ^ | + << >> ?* ? Max ops: 6 ?* ? Rating: 2 ?*/ int isNegative(int x) { ? return ((x>>31)&1); } /* ?* 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 ?*/ int isPower2(int x) { ? int ret = ((!(x&(x+~0))) & ((~(x>>31)&(!!x)))); ? return ret; } /*? ?* addOK - Determine if can compute x+y without overflow ?* ? Example: addOK(0x80000000,0x80000000) = 0, ?* ? ? ? ? ? ?addOK(0x80000000,0x70000000) = 1,? ?* ? Legal ops: ! ~ & ^ | + << >> ?* ? Max ops: 20 ?* ? Rating: 3 ?*/ int addOK(int x, int y) { ? return (((x^y)>>31)|~(((x+y)^x)>>31))&1; } /*? ?* subtractionOK - Determine if can compute x-y without overflow ?* ? Example: subtractionOK(0x80000000,0x80000000) = 1, ?* ? ? ? ? ? ?subtractionOK(0x80000000,0x70000000) = 0,? ?* ? Legal ops: ! ~ & ^ | + << >> ?* ? Max ops: 20 ?* ? Rating: 3 ?*/ 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) ; } /*? ?* oddBits - return word with all odd-numbered bits set to 1 ?* ? Legal ops: ! ~ & ^ | + << >> ?* ? Max ops: 8 ?* ? Rating: 2 ?*/ int oddBits(void) { ? int x = 0xaa; ? x |= x<<8; ? x |= x<<16; ? return x; } /*? ?* replaceByte(x,n,c) - Replace byte n in x with c ?* ? Bytes numbered from 0 (LSB) to 3 (MSB) ?* ? Examples: replaceByte(0x12345678,1,0xab) = 0x1234ab78 ?* ? You can assume 0 <= n <= 3 and 0 <= c <= 255 ?* ? Legal ops: ! ~ & ^ | + << >> ?* ? Max ops: 10 ?* ? Rating: 3 ?*/ int replaceByte(int x, int n, int c) { ? int mask_ = 0xff << (n<<3); ? c <<= (n<<3); ? return (x&(~mask_))|c; } /*? ?* 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? ?*/ int rotateLeft(int x, int n) { ? int mask = (~0) + (1<<n); ? int r = (x>>(32+(~n)+1))&mask; ? return ((x<<n)&(~mask))|r; } /*? ?* floatAbsVal - 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 ?*/ unsigned floatAbsVal(unsigned uf) { ? if((uf&0x7f800000)>>23 == 255 && uf<<9 != 0) return uf; ? return uf & 0x7fffffff; } /*? ?* floatIsEqual - Compute f == g for floating point arguments f and g. ?* ? Both the arguments are passed as unsigned int's, but ?* ? they are to be interpreted as the bit-level representations of ?* ? single-precision floating point values. ?* ? If either argument is NaN, return 0. ?* ? +0 and -0 are considered equal. ?* ? Legal ops: Any integer/unsigned operations incl. ||, &&. also if, while ?* ? Max ops: 25 ?* ? Rating: 2 ?*/ 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; } ?
?
?
?
|