1.更好地熟悉和掌握計算機中整數和浮點數的二進制編碼表示。 2. 加深對數據二進制編碼表示的了解。 3. 使用有限類型和數量的運算操作實現一組給定功能的函數。 |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
實驗原理與內容 計算機實際上只能夠進行邏輯計算——所有的計算類型最終都會轉換為邏輯計算實現,無論多么復雜的功能性計算。所以,本實驗的設計初衷為讓學生進一步理解邏輯計算的各類應用,這有助於增強對於計算機硬件的理解(主要為CPU中的ALU的具體功能和計算實現過程)。為避免繁雜的仿真過程和HDL硬件描述語言的學習,使用標准C語言中的基本運算符和位操作來模擬硬件級別的邏輯計算過程。 實驗要求學生們根據需要對bits.c中的相關函數進行編寫(並修改掉return后面的返回值),實現各個小題所要求的函數功能。主要要求如下:
表1 位操作題目列表
表2 補碼運算題目列表
表3 浮點數操作題目列表(此部分不做強制要求)
根據以上說明,按照各小題的具體要求使用基本運算符和位操作完成bits.c中的函數,使其匹配要求所描述的功能,具體分為三大類:位操作、補碼運算和浮點數操作。
實驗過程中,如果需要對自己的編程結果/成績進行確認,可以使用以下方法: 1. 按照要求使用規定范圍內的操作符和常數實現各函數的功能。 2.函數編寫完成並保存后,可以使用dlc檢查函數實現代碼是否符合實驗要求的編碼規則。具體使用方法如下: a) 首先./dlc bits.c直接檢測是否有不合規或編寫錯誤。如圖1.1所示:
由圖知,輸出Compilation Successful(1 warning),故bits.c文件編寫無強制性錯誤,符合要求。 b) 用-e選項調用dlc,觀察操作符數。得到提示后可通過對比題目要求來檢查使用的操作符個數是否超限,如圖1.2所示:
圖1.2 2. 使用 btest 檢查函數實現代碼的功能正確性並進行成績計算。 a) 首先使用make編譯生成btest可執行程序,如圖1.3所示:
圖1.3 b) 然后調用 btest 命令檢查 bits.c中所有函數的功能正確性。如圖1.4所示:
圖1.4 由圖知,35分中的35分被成功完成(此成績將最后按照百分制進行核算按比例計入實驗成績)。注:最后兩題不做強制性要求,所以不必在乎是否得分為滿分35分。 |
實驗過程與結果(可貼圖) /* * 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; } /* * 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 */ X第n個字節每位都和1異或實現取反 int byteNot(int x, int n) { int y = 0xff; n = n<<3; y = y<<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個字節取出來異或,再轉換為邏輯的0和1 int byteXor(int x, int y, int n) { n = n<<3; x = x>>n; y = y>>n; x = x&(0xff); y = y&(0xff); return !!(x^y); } /* * logicalAnd - x && y * Legal ops: ! ~ & ^ | + << >> * Max ops: 20 * Rating: 3 */ 把x和y分別轉換為邏輯的0和1,再相與 int logicalAnd(int x, int y) { x = (!(!x))&(!(!y)); return x; } /* * logicalOr - x || y * Legal ops: ! ~ & ^ | + << >> * Max ops: 20 * Rating: 3 */ int logicalOr(int x, int y) { x = (!(!x))|(!(!y)); return x; } 把x和y分別轉換為邏輯的0和1,再相或 /* * 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 */ 先構造低n位為1,高(n-32)位為零的數z,x再左移n位后的數加上x右移(32-n)位的數&z即可 int rotateLeft(int x, int n) { int z; z = ~(((1<<31)>>31)<<n); x = ((x>>(32+(~n+1)))&z)+(x<<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 */ 每次將數的低半數位與高半數位比較,再把y右移31位,最后把y轉化為邏輯的0和1 int parityCheck(int x) { int y; y = x<<16; y = y^x; y = y^(y<<8); y = y^(y<<4); y = y^(y<<2); y = y^(y<<1); y = y>>31; 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 */ 把x第30位和30位分別和1做按位與,再異或,再和1異或 int mul2OK(int x) { int m; m = ((x>>30)&0x1)^((x>>30)&0x1); return m^0x1; } /* * 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 */ 左移一位再+x即x*3,右移一位的時候,當y的最高位和最低為都為0時還要加1 int mult3div2(int x) { int y = (x<<1)+x; y = (y>>1)+(((y>>31)&1)&(((y<<31)>>31)&1)); return y; } /* * 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的最高有效位不同且x和(x-y)的最高位不同才能判斷溢出 int subOK(int x, int y) { int m = (x>>31)&1; int n = (y>>31)&1; x = (m^n)&(m^(((x+(~y+1))>>31)&1)); return (!x); } /* * absVal - absolute value of x * Example: absVal(-1) = 1. * You may assume -TMax <= x <= TMax * Legal ops: ! ~ & ^ | + << >> * Max ops: 10 * Rating: 4 */ X的最高位為0時就是x,最高位為1時是~x+1 int absVal(int x) { int y = x>>31; x = (y&(~x+1))+((~y)&x); 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 */ unsigned float_abs(unsigned uf) { return 2; } /* * 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 */ int float_f2i(unsigned uf) { return 2; } 實驗結果截圖:
|
操作異常問題與解決方案 異常:對於按位與、或、異或、加的運算的規則不是很了解 解決:百度+csdn |
實驗總結 經過本次實驗讓我更好地熟悉和掌握計算機中整數的二進制編碼表示。加深對數據二進制編碼表示的了解。使用有限類型和數量的運算操作實現一組給定功能的函數。讓我了解到左移運算將一個位串信息向左移指定的位,右端空出的位用0補充,每左移1位相當於乘2;右移運算將一個位串信息向右移指定的位,右端移出的位的信息被丟棄,每右移1位,相當於除以2。對無符號數據,右移時,左端空出的位用0補充。對於帶符號的數據,如果移位前符號位為0(正數),則左端也是用0補充;如果移位前符號位為1(負數),則左端用0或用1補充,取決於計算機系統。對於負數右移,稱用0補充的系統為“邏輯右移”,用1補充的系統為“算術右移”。按位取反為二進制串對應的1和0進行變換邏輯取反只有0和非0兩種情況
|
實驗原理與內容 計算機實際上只能夠進行邏輯計算——所有的計算類型最終都會轉換為邏輯計算實現,無論多么復雜的功能性計算。所以,本實驗的設計初衷為讓學生進一步理解邏輯計算的各類應用,這有助於增強對於計算機硬件的理解(主要為CPU中的ALU的具體功能和計算實現過程)。為避免繁雜的仿真過程和HDL硬件描述語言的學習,使用標准C語言中的基本運算符和位操作來模擬硬件級別的邏輯計算過程。 實驗要求學生們根據需要對bits.c中的相關函數進行編寫(並修改掉return后面的返回值),實現各個小題所要求的函數功能。主要要求如下:
表1 位操作題目列表
表2 補碼運算題目列表
表3 浮點數操作題目列表(此部分不做強制要求)
根據以上說明,按照各小題的具體要求使用基本運算符和位操作完成bits.c中的函數,使其匹配要求所描述的功能,具體分為三大類:位操作、補碼運算和浮點數操作。
實驗過程中,如果需要對自己的編程結果/成績進行確認,可以使用以下方法: 1. 按照要求使用規定范圍內的操作符和常數實現各函數的功能。 2.函數編寫完成並保存后,可以使用dlc檢查函數實現代碼是否符合實驗要求的編碼規則。具體使用方法如下: a) 首先./dlc bits.c直接檢測是否有不合規或編寫錯誤。如圖1.1所示:
圖1.1 由圖知,輸出Compilation Successful(1 warning),故bits.c文件編寫無強制性錯誤,符合要求。 b) 用-e選項調用dlc,觀察操作符數。得到提示后可通過對比題目要求來檢查使用的操作符個數是否超限,如圖1.2所示:
圖1.2 2. 使用 btest 檢查函數實現代碼的功能正確性並進行成績計算。 a) 首先使用make編譯生成btest可執行程序,如圖1.3所示:
圖1.3 b) 然后調用 btest 命令檢查 bits.c中所有函數的功能正確性。如圖1.4所示:
圖1.4 由圖知,35分中的35分被成功完成(此成績將最后按照百分制進行核算按比例計入實驗成績)。注:最后兩題不做強制性要求,所以不必在乎是否得分為滿分35分。 |