# 2018q3 Homework5 (bits) contributed by <[`yungchuan`](https://github.com/yungchuan)> ## 安裝 32-bit 開發套件 在開始進行程式開發之前,需要先安裝 32-bit 的開發套件 ```bash $ sudo apt install libc6-dev:i386 gcc:i386 ``` 得到以下訊息: ```bash Reading package lists... Done Building dependency tree Reading state information... Done Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable distribution that some required packages have not yet been created or been moved out of Incoming. The following information may help to resolve the situation: The following packages have unmet dependencies: gcc:i386 : Depends: cpp:i386 (>= 4:5.3.1-1ubuntu1) but it is not going to be installed Depends: gcc-5:i386 (>= 5.3.1-3~) but it is not going to be installed E: Unable to correct problems, you have held broken packages. ``` 從訊息描述了解,安裝套件之前必須預先安裝 `cpp:i386` 以及 `gcc-5:i386` 所以依照指示安裝 ```bash $ sudo apt install cpp:i386 gcc-5:i386 ``` 得到訊息 ```bash Reading package lists... Done Building dependency tree Reading state information... Done Some packages could not be installed. This may mean that you have requested an impossible situation or if you are using the unstable distribution that some required packages have not yet been created or been moved out of Incoming. The following information may help to resolve the situation: The following packages have unmet dependencies: gcc-5:i386 : Depends: binutils:i386 (>= 2.26.1) but it is not going to be installed E: Unable to correct problems, you have held broken packages. ``` 訊息表示缺少 `binutils:i386` 這個套件,所以再多安裝這個套件 ```bash $ sudo apt install binutils:i386 ``` 得到安裝成功的訊息,如此再依序把剛才未安裝成功的套件安裝好,就可以開始這次的程式開發。 ## 程式開發 ### absval #### 想法 使用 bitwise 的操作來取整數的絕對值,正數必須不變、負數變成正數。 利用 2 補數的特性,負數的 most significant bit 為 1,而任何數對全 bit 皆為 1 的數做 xor 會變成 1 補數,只要再加 1 就會變成 2 補數。 #### 程式碼 ```C int absVal(int x) { int y = x >> 31; return (x ^ y) + (~y + 1); } ``` ### addOK #### 想法 確認兩數相加是否會 overflow 如果兩數異號,相加必不會 overflow ;如果同號且相加後不會 overflow ,則相加後與相加前會同號。 #### 程式碼 ```C int addOK(int x, int y) { int a = x >> 31; int b = y >> 31; int cont1 = a ^ b; int c = (x + y) >> 31; int cont2 = ~(c ^ a); return (cont1 | (~cont1 & cont2)) & 1; } ``` ### allEvenBits #### 想法 總共 32 bits ,將總 bits 數分成兩半來做 and 運算,做完再分,直到剩 2 個 bits 時,第 0 個 bit 代表的就是所有偶數 bits 互相 and 後的結果,如果全部偶數 bits 都為 1 的話,結果就是 1。 #### 程式碼 ```C int allEvenBits(int x) { x &= x >> 16; x &= x >> 8; x &= x >> 4; x &= x >> 2; return x & 1; } ``` ### allOddBits #### 想法 總共 32 bits ,將總 bits 數分成兩半來做 and 運算,做完再分,直到剩 2 個 bits 時,第 1 個 bit 代表的就是所有奇數 bits 互相 and 後的結果,如果全部奇數 bits 都為 1 的話,結果就是 1。 #### 程式碼 ```C int allOddBits(int x) { x &= x >> 16; x &= x >> 8; x &= x >> 4; x &= x >> 2; return (x & 2) >> 1; } ``` ### anyEvenBit #### 想法 總共 32 bits ,將總 bits 數分成兩半來做 or 運算,做完再分,直到剩 2 個 bits 時,第 0 個 bit 代表的就是所有偶數 bits 互相 or 後的結果,如果全部偶數 bits 中有一個 1 的話,結果就是 1。 #### 程式碼 ```C int anyEvenBit(int x) { x |= x >> 16; x |= x >> 8; x |= x >> 4; x |= x >> 2; return x & 1; } ``` ### anyEvenBit #### 想法 總共 32 bits ,將總 bits 數分成兩半來做 or 運算,做完再分,直到剩 2 個 bits 時,第 1 個 bit 代表的就是所有奇數 bits 互相 or 後的結果,如果全部奇數 bits 中有一個 1 的話,結果就是 1。 #### 程式碼 ```C int anyOddBit(int x) { x |= x >> 16; x |= x >> 8; x |= x >> 4; x |= x >> 2; return (x & 2) >> 1; } ``` ### bang #### 想法 要實做出 ! 運算,首先就要確認全部 bits 中有沒有 1,若有就必須回傳 0;若沒有 (即0) 則回傳 1。 每次將整個數分半 (左移) 做 or 運算直到每個 bit 都運算過,如此第 31 個 bit 代表全部的 bits 互相做 or 運算的結果,只要有一個 1,結果就為 1 ,將其右移 31 bits 後若剛才結果為 1 就會變成 -1 ,為 0 的話結果就為 0,只要加 1 即為要求。 #### 程式碼 ```C int bang(int x) { x |= x << 16; x |= x << 8; x |= x << 4; x |= x << 2; x |= x << 1; return (x >> 31) + 1; } ``` ### bitAnd #### 想法 觀察真值表後的結論。 將兩數取 not 後做 or 運算再取 not 即跟 and 運算的結果相同 。 #### 程式碼 ```C int bitAnd(int x, int y) { return ~(~x | ~y); } ``` ### bitCount #### 想法 每次將整個數分半,將第 0 bit 與第 16 bit 相加、第 1 bit 與第 17 bit 相加;依此類推。加完後再分半,再相加。到最後會代表所有 bits 相加的結果 (有實做上的細節要注意) ,有幾個 1 數字就會是多少。 #### 程式碼 ```C int bitCount(int x) { int sample = (((((0x55 << 8) + 0x55) << 8) + 0x55) << 8) + 0x55; int y = x >> 1; int x1 = x & sample; int y1 = y & sample; x = x1 + y1; sample = (((((0x33 << 8) + 0x33) << 8) + 0x33) << 8) + 0x33; y = x >> 2; x1 = x & sample; y1 = y & sample; x = x1 + y1; sample = (((((0x0f << 8) + 0x0f) << 8) + 0x0f) << 8) + 0x0f; y = x >> 4; x1 = x & sample; y1 = y & sample; x = x1 + y1; sample = (0xff << 16) + 0xff; y = x >> 8; x1 = x & sample; y1 = y & sample; x = x1 + y1; y = x << 16; x += y; x = x >> 16; return x; } ``` ### bitMask #### 想法 只要用一個全 bits 皆為 1 的變數,透過左移右移的操作就可以實做出來。 #### 程式碼 ```C int bitMask(int highbit, int lowbit) { int a = (1 << 31) >> 31; int b = a << highbit; b = ~(b << 1); int c = (a << lowbit); a = b & c; return a; } ``` ### bitMatch #### 想法 match 的慨念就是 and ,只是兩數同 bit 皆為 0 的話也算是 match ,所以要取 not 再 and 一次。 #### 程式碼 ```C int bitMatch(int x, int y) { int a = x & y; int b = (~x) & (~y); return a | b; } ``` ### bitNor #### 想法 觀察真值表,兩數分別取 not 後做 and 運算即跟 or 後取 not 的結果一樣。 #### 程式碼 ```C int bitNor(int x, int y) { return (~x) & (~y); } ``` ### bitOr #### 想法 觀察真值表,兩數分別取 not 後做 and 運算後再取一次 not 即跟 or 運算的結果一樣。 #### 程式碼 ```C int bitOr(int x, int y) { return ~((~x) & (~y)); } ``` ### bitParity #### 想法 要檢查有沒有奇數個 1 ,只需要將全部的 bits 一起做 xor 運算,因為 xor 只要相同就會為 0 ,所以只要有奇數個 1 就會有一對是沒有跟相同數字配對的,運算結果就會是 1 ,將其回傳即為所求。 #### 程式碼 ```C int bitParity(int x) { x ^= x >> 16; x ^= x >> 8; x ^= x >> 4; x ^= x >> 2; x ^= x >> 1; return x & 1; } ``` ### bitReverse #### 想法 要將所有的 bits 反向可以先藉由將兩個 bits 交換,接著再兩個 bits 一組再兩兩交換,依此類推就能將整個變數反像了。 #### 程式碼 ```C int bitReverse(int x) { int sample = (((((0x55 << 8) + 0x55) << 8) + 0x55) << 8) + 0x55; int y = x >> 1; x = (x & sample) << 1; y = y & sample; x = x | y; sample = (((((0x33 << 8) + 0x33) << 8) + 0x33) << 8) + 0x33; y = x >> 2; x = (x & sample) << 2; y = y & sample; x = x | y; sample = (((((0x0f << 8) + 0x0f) << 8) + 0x0f) << 8) + 0x0f; y = x >> 4; x = (x & sample) << 4; y = y & sample; x = x | y; sample = (0xff << 16) + 0xff; y = x >> 8; x = (x & sample) << 8; y = y & sample; x = x | y; sample = (0xff << 8) + 0xff; y = x >> 16; x = (x & sample) << 16; y = y & sample; x = x | y; return x; } ``` ### bitXor #### 想法 觀察真值表可以發現,只要將兩變數進行 or 運算以及取 not 後再進行 or 運算,將這兩個結果進行 and 運算後,其行為就跟 xor 一樣。 #### 程式碼 ```C int bitXor(int x, int y) { return (x | y) & (~x | ~y); } ``` ### byteSwap #### 想法 分別記錄要交換的兩個 byte 並且將原變數該 byte 的位置清空,接著將記錄好的 byte 寫入要交換的位置。 #### 程式碼 ```C int byteSwap(int x, int n, int m) { int a = 0xff; int b1 = n << 3; int c1 = x >> b1; c1 = c1 & a; x = x & (~(a << b1)); int b2 = m << 3; int c2 = x >> b2; c2 = c2 & a; x = x & (~(a << b2)); c1 = c1 << b2; c2 = c2 << b1; x = x | c1 | c2; return x; } ``` ### conditional #### 想法 當 x 不為 0 時要回傳 y ,當 x 為 0 時則要回傳 z 。那我們可以依照 x 的值設定兩個變數,分別為全 bits 皆 1 以及全 bits 皆 0 ,當 x 不為 0 時,跟 y 做 and 運算的變數值為全 1,跟 z 做 and 的變數值為全 0 ,當 x 為 0 時則相反。兩數 and 運算完後在 or 運算即為所求。 #### 程式碼 ```C int conditional(int x, int y, int z) { int a = ~!!x + 1; int b = ~!x + 1; int c = a & y; int d = b & z; return c | d; } ``` ### countLeadingZero #### 想法 #### 程式碼 未完成 ### copyLSB #### 想法 只須將 LSB 左移到 sign bit 再右移回來即可。 #### 程式碼 ```C int copyLSB(int x) { return (x << 31) >> 31; } ``` ### distinctNegation #### 想法 x != -x ,如此我們就用 2 補數的原則取得 -x ,再與 x 做 xor 判斷是否相等。 #### 程式碼 ```C int distinctNegation(int x) { return !!(x ^ (~x + 1)); } ``` ### dividePower2 #### 想法 除以 2 的指數,在二進位中只須右移指數的數值即可。不過要注意負數的的捨入。 #### 程式碼 ```C int dividePower2(int x, int n) { int a = x >> n; int b = x ^ (a << n); return a + ((!!b) & (x >> 31)); } ``` ### evenBits #### 想法 直接回傳要求數值。 #### 程式碼 ```C int evenBits(void) { return (((((0x55 << 8) + 0x55) << 8) + 0x55) << 8) + 0x55; } ``` ### ezThreeFourths #### 想法 3/4 可以轉換成 2 倍 + 1 倍除 4 ,要注意負數的捨入。 #### 程式碼 ```C int ezThreeFourths(int x) { int a = (x << 1) + x; int b = a >> 2; int c = a ^ (b << 2); return b + ((!!c) & (b >> 31)); } ``` ### fitsBits #### 想法 因為有 sign bit 的關係,所以要檢查 n - 1 個 bit 能否完整表示。所想到的方法是移動了 n - 1 個 bits 之後如果跟他移動 31 bits 的結果一樣就是可以用 n 個 bits 表示。 #### 程式碼 ```C int fitsBits(int x, int n) { int a = (1 << 31) >> 31; n += a; int sig = x >> 31; return !((x >> n) ^ sig); } ``` ### fitsShort #### 想法 #### 程式碼 ```C int fitsShort(int x) { return !((x >> 15) ^ (x >> 31)); } ``` ### floatAbsVal #### 想法 #### 程式碼 ```C unsigned floatAbsVal(unsigned uf) { unsigned a = (uf << 1) ^ 0xff000000; if (a > 0 && a < 0x01000000) return uf; return uf & (~(1 << 31)); } ``` ### floatFloat2Int #### 想法 #### 程式碼 ### floatInt2Float #### 想法 #### 程式碼 ### floatIsEqual #### 想法 #### 程式碼 ```C int floatIsEqual(unsigned uf, unsigned ug) { unsigned a = (uf << 1) ^ 0xff000000; if (a > 0 && a < 0x01000000) return 0; a = (ug << 1) ^ 0xff000000; if (a > 0 && a < 0x01000000) return 0; if ((uf << 1) == 0 && (ug << 1) == 0) return 1; a = uf ^ ug; if (!a) return 1; return 0; } ``` ### floatIsLess #### 想法 #### 程式碼 ```C int floatIsLess(unsigned uf, unsigned ug) { unsigned a = (uf << 1) ^ 0xff000000; if (a > 0 && a < 0x01000000) return 0; a = (ug << 1) ^ 0xff000000; if (a > 0 && a < 0x01000000) return 0; if ((uf << 1) == 0 && (ug << 1) == 0) return 0; int sf = uf >> 31, sg = ug >> 31; a = sf + sg; if (a == 0) return uf < ug; else if (a == 2) return ug < uf; else return sf; } ``` ### floatNegate #### 想法 #### 程式碼 ```C unsigned floatNegate(unsigned uf) { unsigned a = (uf << 1) ^ 0xff000000; if (a > 0 && a < 0x01000000) return uf; return uf ^ 0x80000000; } ``` ### floatPower2 #### 想法 #### 程式碼 ```C unsigned floatPower2(int x) { if (x > 127) return 0x7f800000; else if (x < -149) return 0; else if (x + 127 > 0) return (x + 127) << 23; else return 0x00800000 >> (-x - 126); } ``` ### floatScale1d2 #### 想法 #### 程式碼 ```C unsigned floatScale1d2(unsigned uf) { unsigned sf = uf & 0x80000000; unsigned ef = uf & 0x7f800000; unsigned ff = uf & 0x007fffff; if (ef == 0) { if ((ff & 0x3) == 0x3) ff += 0x1; return sf | (ff >> 1); } else if (ef - 0x800000 == 0) { if ((ff & 0x3) == 0x3) ff += 0x1; return sf | ((ef | ff) >> 1); } else if (ef != 0x7f800000) return sf | (ef - 0x00800000) | ff; return uf; } ``` ### floatScale2 #### 想法 #### 程式碼 ```C unsigned floatScale2(unsigned uf) { unsigned sf = uf & 0x80000000; unsigned ef = uf & 0x7f800000; unsigned ff = uf & 0x007fffff; if (ef == 0) return sf | (ff << 1); else if (ef != 0x7f800000) return sf | (ef + 0x00800000) | ff; return uf; } ``` ### floatScale64 #### 想法 #### 程式碼 ### floatUnsigned2Float #### 想法 #### 程式碼 ### getByte #### 想法 #### 程式碼 ```C int getByte(int x, int n) { n = n << 3; return (x >> n) & 0xff; } ``` ### greatestBitPos #### 想法 #### 程式碼 ### howManyBits #### 想法 #### 程式碼 ### implication #### 想法 #### 程式碼 ```C int implication(int x, int y) { return (!x) | (x & y); } ``` ### intLog2 #### 想法 #### 程式碼 ### isAsciiDigit #### 想法 #### 程式碼 ```C int isAsciiDigit(int x) { int a = 0x39 + (~x) + 1; int b = x + (~(0x30)) + 1; a = ~(a >> 31); int c = ~(b >> 31); return a & (!!(b + 1)) & c; } ``` ### isEqual #### 想法 #### 程式碼 ```C int isEqual(int x, int y) { return !(x ^ y); } ``` ### isGreater #### 想法 #### 程式碼 ```C int isGreater(int x, int y) { int ny = ~y + 1; return (((~((x >> 31) ^ (y >> 31))) & (~((x + ny) >> 31))) | (((x >> 31) ^ (y >> 31)) & (~(x >> 31)))) & (!!(x ^ y)); } ``` ### isLess #### 想法 #### 程式碼 ```C int isLess(int x, int y) { int ny = ~y + 1; return (((~((x >> 31) ^ (y >> 31))) & ((x + ny) >> 31)) | (((x >> 31) ^ (y >> 31)) & (x >> 31))) & 1; } ``` ### isLessOrEqual #### 想法 #### 程式碼 ```C int isLessOrEqual(int x, int y) { int ny = ~y + 1; return !((((~((x >> 31) ^ (y >> 31))) & (~((x + ny) >> 31))) | (((x >> 31) ^ (y >> 31)) & (~(x >> 31)))) & (!!(x ^ y))); } ``` ### isNegative #### 想法 #### 程式碼 ```C int isNegative(int x) { return !!(x >> 31); } ``` ### isNonNegative #### 想法 #### 程式碼 ```C int isNonNegative(int x) { return !(x >> 31); } ``` ### isNonZero #### 想法 #### 程式碼 ```C int isNonZero(int x) { return !!x; } ``` ### isNotEqual #### 想法 #### 程式碼 ```C int isNotEqual(int x, int y) { return !!(x ^ y); } ``` ### isPallindrome #### 想法 #### 程式碼 ```C int isPallindrome(int x) { int sample = (((((0x55 << 8) + 0x55) << 8) + 0x55) << 8) + 0x55; int y = x >> 1; int z = (x & sample) << 1; y = y & sample; z = z | y; sample = (((((0x33 << 8) + 0x33) << 8) + 0x33) << 8) + 0x33; y = z >> 2; z = (z & sample) << 2; y = y & sample; z = z | y; sample = (((((0x0f << 8) + 0x0f) << 8) + 0x0f) << 8) + 0x0f; y = z >> 4; z = (z & sample) << 4; y = y & sample; z = z | y; sample = (0xff << 16) + 0xff; y = z >> 8; z = (z & sample) << 8; y = y & sample; z = z | y; sample = (0xff << 8) + 0xff; y = z >> 16; z = (z & sample) << 16; y = y & sample; z = z | y; return !(x ^ z); } ``` ### isPositive #### 想法 #### 程式碼 ```C int isPositive(int x) { return !(x >> 31) & !!x; } ``` ### isPower2 #### 想法 #### 程式碼 ```C int isPower2(int x) { x = ~(x & (x >> 16)); return 42; } ``` ### isTmax #### 想法 #### 程式碼 ```C int isTmax(int x) { return (!((~x) << 1)) & (!!(~x)); } ``` ### isTmin #### 想法 #### 程式碼 ```C int isTmin(int x) { return (!(x << 1)) & (!!x); } ``` ### isZero #### 想法 #### 程式碼 ```C int isZero(int x) { return !x; } ``` ### leastBitPos #### 想法 #### 程式碼 ```C int leastBitPos(int x) { return x & ((~x) + 1); } ``` ### leftBitCount #### 想法 #### 程式碼 ### logicalNeg #### 想法 #### 程式碼 ```C int logicalNeg(int x) { x = x | (x >> 16); x = x | (x >> 8); x = x | (x >> 4); x = x | (x >> 2); x = x | (x >> 1); return (x & 1) ^ 1; } ``` ### logicalShift #### 想法 #### 程式碼 ```C int logicalShift(int x, int n) { x = x >> n; int a = 1 << 31; a = a >> n; a = (a << 1); return x & (~a); } ``` ### maximumOfTwo #### 想法 #### 程式碼 ```C int maximumOfTwo(int x, int y) { int diff = x + (~y) + 1; int sx = x >> 31, sy = y >> 31; //(sx ^ sy) & ((sx & y) | (sy & x)); //(~(sx ^ sy)) & (((~((x + ny) >> 31)) & x) | (((x + ny) >> 31) & y)) return ((sx ^ sy) & ((sx & y) | (sy & x))) | ((~(sx ^ sy)) & (((~(diff >> 31)) & x) | ((diff >> 31) & y))); } ``` ### minimumOfTwo #### 想法 #### 程式碼 ```C int minimumOfTwo(int x, int y) { int diff = x + (~y) + 1; int sx = x >> 31, sy = y >> 31; //(sx ^ sy) & ((sx & y) | (sy & x)); //(~(sx ^ sy)) & (((~((x + ny) >> 31)) & x) | (((x + ny) >> 31) & y)) return ((sx ^ sy) & ((sx & x) | (sy & y))) | ((~(sx ^ sy)) & (((~(diff >> 31)) & y) | ((diff >> 31) & x))); } ``` ### minusOne #### 想法 #### 程式碼 ```C int minusOne(void) { return (1 << 31) >> 31; } ``` ### multFiveEights #### 想法 #### 程式碼 ```C int multFiveEighths(int x) { int s = x >> 31; int t = (x << 2) + x; return ((~s) & (t >> 3)) | (s & ((t + 7) >> 3)); } ``` ### negate #### 想法 #### 程式碼 ```C int negate(int x) { return (~x) + 1; } ``` ### oddBits #### 想法 #### 程式碼 ```C int oddBits(void) { int x = 2; x = (x << 2) + x; x = (x << 4) + x; x = (x << 8) + x; x = (x << 16) + x; return x; } ``` ### remainderPower2 #### 想法 #### 程式碼 ```C int remainderPower2(int x, int n) { int s = x >> 31; int a = (1 << 31) >> 31; a = ~(a << n); return ((~s) & x & a) | (s & (~((~x + 1) & a) + 1)); } ``` ### replaceByte #### 想法 #### 程式碼 ```C int replaceByte(int x, int n, int c) { n = n << 3; int a = 0xff << n; x = x & (~a); return x + (c << n); } ``` ### rotateLeft #### 想法 #### 程式碼 ```C int rotateLeft(int x, int n) { int a = ((1 << 31) >> 31) << n; int b = (x >> (31 + (~n) + 1)) >> 1; a = (~a) & b; return (x << n) + a; } ``` ### rotateRight #### 想法 #### 程式碼 ```C int rotateRight(int x, int n) { int a = ~(((1 << 31) >> n) << 1); int b = (x << (31 + (~n) + 1)) << 1; return ((x >> n) & a) + b; } ``` ### satAdd #### 想法 #### 程式碼 ```C int satAdd(int x, int y) { int sx = x >> 31, sy = y >> 31; int sxy = (x + y) >> 31; return ((sx ^ sy) & (x + y)) | (~(sx ^ sy) & (((sx ^ sxy) & (sx ^ (~(1 << 31)))) | (~(sx ^ sxy) & (x + y)))); } ``` ### satMul2 #### 想法 #### 程式碼 ```C int satMul2(int x) { int sx = x >> 31; int r = x + x; int sr = r >> 31; return (~(sx ^ sr) & r) | ((sx ^ sr) & ((~(1 << 31)) ^ sx)); } ``` ### satMul3 #### 想法 #### 程式碼 ```C int satMul3(int x) { int sx = x >> 31; int r = x + x; int sr = r >> 31; int x2 = (~(sx ^ sr) & r) | ((sx ^ sr) & ((~(1 << 31)) ^ sx)); sx = x2 >> 31; r = x2 + x; sr = r >> 31; return (~(sx ^ sr) & r) | ((sx ^ sr) & ((~(1 << 31)) ^ sx)); } ``` ### sign #### 想法 #### 程式碼 ```C int sign(int x) { return (~((~x + 1) >> 31) + 1) | (x >> 31); } ``` ### signMaag2TwosComp #### 想法 #### 程式碼 ```C int signMag2TwosComp(int x) { int s = x >> 31; x = x & (~(1 << 31)); return (x ^ s) + (~s + 1); } ``` ### specialBits #### 想法 #### 程式碼 ```C int specialBits(void) { int a = ~0x0; int b = 0xd7 << 14; return a ^ b; } ``` ### subtractionOK #### 想法 #### 程式碼 ```C int subtractionOK(int x, int y) { int sx = x >> 31, sy = y >> 31; int ny = ~y + 1; // int sny = ny >> 31; return (!(sx ^ sy)) | ((sx ^ sy) & !(((x + ny) >> 31) ^ sx)); } ``` ### thirdBits #### 想法 #### 程式碼 ```C int thirdBits(void) { int a = 1; a = (a << 3) + a; a = (a << 6) + a; a = (a << 12) + a; a = (a << 24) + a; return a; } ``` ### tmax #### 想法 #### 程式碼 ```C int tmax(void) { return ~(1 << 31); } ``` ### tmin #### 想法 #### 程式碼 ```C int tmin(void) { return 1 << 31; } ``` ### trueFiveEighths #### 想法 #### 程式碼 ### trueThreeFourths #### 想法 #### 程式碼 ### twosComp2SignMag #### 想法 #### 程式碼 ```C int twosComp2SignMag(int x) { int s = x >> 31; int absx = (x ^ s) + (~s + 1); return ((!!s) << 31) + absx; } ``` ### upperBits #### 想法 #### 程式碼 ```C int upperBits(int n) { int a = n + (~(n >> 1) + 1); return (((1 << 31) >> a) << 1) >> (n >> 1); } ```