2018q3 Homework5 (bits) === contributed by<[LiuJuiHung](https://github.com/LiuJuiHung/datalab)> ## 實驗環境 ``` $ lscpu Architecture: x86_64 CPU op-mode(s): 32-bit, 64-bit Byte Order: Little Endian CPU(s): 4 On-line CPU(s) list: 0-3 Thread(s) per core: 1 Core(s) per socket: 4 Socket(s): 1 NUMA node(s): 1 Vendor ID: GenuineIntel CPU family: 6 Model: 58 Model name: Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz Stepping: 9 CPU MHz: 1617.917 CPU max MHz: 3600.0000 CPU min MHz: 1600.0000 BogoMIPS: 6400.24 Virtualization: VT-x L1d cache: 32K L1i cache: 32K L2 cache: 256K L3 cache: 6144K NUMA node0 CPU(s): 0-3 ``` ## 無法 make make 時發現以下錯誤 ``` $ make Git commit hooks are installed successfully. gcc -O0 -g -Wall -Werror -m32 -lm -o btest bits.c btest.c decl.c tests.c In file included from /usr/include/stdio.h:27:0, from btest.c:17: /usr/include/features.h:367:25: fatal error: sys/cdefs.h: No such file or directory compilation terminated. In file included from /usr/include/stdio.h:27:0, from decl.c:1: /usr/include/features.h:367:25: fatal error: sys/cdefs.h: No such file or directory compilation terminated. In file included from /usr/include/limits.h:25:0, from /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/limits.h:168, from /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/syslimits.h:7, from /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/limits.h:34, from tests.c:3: /usr/include/features.h:367:25: fatal error: sys/cdefs.h: No such file or directory compilation terminated. Makefile:13: recipe for target 'btest' failed make: *** [btest] Error 1 ``` [解決方法](https://stackoverflow.com/questions/4643197/missing-include-bits-cconfig-h-when-cross-compiling-64-bit-program-on-32-bit),下`$ sudo apt install gcc-multilib`指令安裝`gcc-multilib`即可 ## 修改 bit.c ### absVal :::info 規定: * absVal - absolute value of x * Example: absVal(-1) = 1. * You may assume -TMax <= x <= TMax * Legal ops: ! ~ & ^ | + << >> * Max ops: 10 * Rating: 4 ::: 簡單推導如下,以 4-bits 進行推導: ``` 1 0 0 1 x (因 x 為有號數,所以此二進制的 "1001" 代表十進制的 "-7") 1 1 1 1 y = x >> 3 ------------------ 0 1 1 0 (y ^ x) 0 0 0 1 (~y + 1) ------------------ 0 1 1 1 (y ^ x)+ (~y + 1) result "7" ``` ```Clike=1 int absVal(int x) { int y = x >> 31; return (y ^ x) + (~y + 1); } ``` ### addOK :::info 規定: * 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 ::: * 正加正,負加負兩者皆可能有溢位產生 * 正加負不會造成溢位 ```Clike=1 int addOK(int x, int y) { int z = x + y; return !(((x ^ z) & (y ^ z)) >> 31); } ``` ### allEventBits :::info 規定: * allEvenBits - return 1 if all even-numbered bits in word set to 1 * where bits are numbered from 0 (least significant) to 31 (most significant) * Examples allEvenBits(0xFFFFFFFE) = 0, allEvenBits(0x55555555) = 1 * Legal ops: ! ~ & ^ | + << >> * Max ops: 12 * Rating: 2 ::: 利用 `&` 來確認是否每個偶數位元都等於 `1` ```Clike=1 int allEvenBits(int x) { x &= x >> 16; x &= x >> 8; x &= x >> 4; x &= x >> 2; return x & 0x1; } ``` ### allOddBits :::info 規定: * allOddBits - return 1 if all odd-numbered bits in word set to 1 * where bits are numbered from 0 (least significant) to 31 (most significant) * Examples allOddBits(0xFFFFFFFD) = 0, allOddBits(0xAAAAAAAA) = 1 * Legal ops: ! ~ & ^ | + << >> * Max ops: 12 * Rating: 2 ::: 利用 `&` 來確認是否每個奇數位元都等於 `1`,並在最後`>> 1‵ ```Clike=1 int allOddBits(int x) { x &= x >> 16; x &= x >> 8; x &= x >> 4; x &= x >> 2; x = x >> 1; return x & 0x1; } ``` ### anyEvenBit :::info 規定: * anyEvenBit - return 1 if any even-numbered bit in word set to 1 * where bits are numbered from 0 (least significant) to 31 (most significant) * Examples anyEvenBit(0xA) = 0, anyEvenBit(0xE) = 1 * Legal ops: ! ~ & ^ | + << >> * Max ops: 12 * Rating: 2 ::: 只要任意偶數位元有 `1`, 則輸出 `1`;若偶數位元皆為 `0`,則輸出 `0` ```Clike=1 int anyEvenBit(int x) { x |= x >> 16; x |= x >> 8; x |= x >> 4; x |= x >> 2; return x & 0x1; } ``` ### anyOddBit ::: info 規定: * anyOddBit - return 1 if any odd-numbered bit in word set to 1 * where bits are numbered from 0 (least significant) to 31 (most significant) * Examples anyOddBit(0x5) = 0, anyOddBit(0x7) = 1 * Legal ops: ! ~ & ^ | + << >> * Max ops: 12 * Rating: 2 ::: 只要任意奇數位元有 `1`, 則輸出 `1`;若奇數位元皆為 `0`,則輸出 `0` ```Clike=1 int anyOddBit(int x) { x |= x >> 16; x |= x >> 8; x |= x >> 4; x |= x >> 2; x = x >> 1; return x & 0x1; } ``` ### bang :::info 規定: * bang - Compute !x without using ! * Examples: bang(3) = 0, bang(0) = 1 * Legal ops: ~ & ^ | + << >> * Max ops: 12 * Rating: 4 ::: 讓非 `0` 的數變成 `0`,讓 `0` 變成 `1` ```Clike=1 int bang(int x) { return (1 & (1 ^ ((x | (~x + 1)) >> 31))); } ``` ### bitAnd :::info 規定: * bitAnd - x&y using only ~ and | * Example: bitAnd(6, 5) = 4 * Legal ops: ~ | * Max ops: 8 * Rating: 1 ::: 利用 `De Morgan's laws` 做推導 $XY = \overline{\overline{\rm XY}} = \overline{ \overline{\rm X} \ + \ \overline{\rm Y}}$ ```Clike=1 int bitAnd(int x, int y) { return ~((~x) | (~y)); } ``` ### bitCount :::info 規定: * bitCount - returns count of number of 1's in word * Examples: bitCount(5) = 2, bitCount(7) = 3 * Legal ops: ! ~ & ^ | + << >> * Max ops: 40 * Rating: 4 ::: :::danger 先跳過 ::: ### bitMask :::info 規定: * 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 ::: :::danger 先跳過 ::: ### bitMatch :::info 規定: * 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 ::: :::danger 先跳過 ::: ### bitNor :::info 規定: * bitNor - ~(x|y) using only ~ and & * Example: bitNor(0x6, 0x5) = 0xFFFFFFF8 * Legal ops: ~ & * Max ops: 8 * Rating: 1 ::: 利用 `De Morgan's laws` 做推導 $\overline{\rm X+Y} \ = \ \overline{\rm X} \bullet \overline{\rm Y}$ ```Clike=1 int bitNor(int x, int y) { return (~x) & (~y); } ``` ### bitOr :::info 規定: * bitOr - x|y using only ~ and & * Example: bitOr(6, 5) = 7 * Legal ops: ~ & * Max ops: 8 * Rating: 1 ::: 利用 `De Morgan's laws` 做推導 $X+Y = \overline{\overline{\rm X+Y}} = \overline{\overline{\rm X} + \overline{\rm Y}}$ ```Clike=1 int bitOr(int x, int y) { return ~((~x) & (~y)); } ``` ### bitParity :::info 規定: * 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 ::: 透過 `shift right` 與 `XOR` 計算 1 有偶數還是奇數個,以下為 8-bit 為例推導 ``` 10101010 x 00001010 x >> 4 ------------------ 10100000 y = x ^ (x>>4) 00101000 z = y >> 2 ------------------ 10001000 a = y ^ z 01000100 b = a >> 1 ------------------ 11001100 LSB = 0,為偶數個1 ============================== 10101000 x 00001010 x >> 4 ------------------ 10100010 y = x ^ (x>>4) 00101000 z = y >> 2 ------------------ 10001010 a = y ^ z 01000101 b = a >> 1 ------------------ 11001111 LSB = 1,為奇數個1 ``` ```Clike=1 int bitParity(int x) { x ^= x >> 16; x ^= x >> 8; x ^= x >> 4; x ^= x >> 2; x ^= x >> 1; return x & 1; } ``` ### bitReverse :::info 規定: * bitReverse - Reverse bits in a 32-bit word * Examples: * bitReverse(0x80000002) = 0x40000001 * bitReverse(0x89ABCDEF) = 0xF7D3D591 * Legal ops: ! ~ & ^ | + << >> * Max ops: 45 * Rating: 4 ::: :::danger 先跳過 ::: ### bitXOR :::info 規定: * bitXor - x^y using only ~ and & * Example: bitXor(4, 5) = 1 * Legal ops: ~ & * Max ops: 14 * Rating: 1 ::: 利用 `De Morgan's laws`,`真值表`,`XOR等價公式` 做推導 $X \oplus Y = (\overline{\rm X} \bullet Y) + (X \bullet \overline{\rm Y})$ ```Clike=1 int bitXor(int x, int y) { return ((~x) & y) + (x & (~y)); } ``` ### byteSwap :::info 規定: * 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 :::