# 2018q3 Homework5 (bits)
contributed by < `type59ty` >
##### tags:`hw5`,`bits`
---
## 實驗環境
```c
Linux version 4.15.0-36-generic (buildd@lgw01-amd64-031)
Description: Ubuntu 18.04.1 LTS
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz x 12
GPU : GeForce GTX 1080 Ti x 2
memory: 32G
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 12288K
gcc version: 7.3.0
```
## 預期目標
- 深度學習 [CS:APP](https://hackmd.io/c/S1vGugaDQ) 第 2 章和對應的補充教材
- 跨越理論與實務的鴻溝
- [找出詳解錯誤](https://www.viseator.com/2017/06/18/CS_APP_DataLab/)
## 作業要求
* 自 GitHub 上 fork [datalab](https://github.com/sysprog21/datalab),依據 [Data Lab: Manipulating Bits](http://csapp.cs.cmu.edu/3e/datalab.pdf),補完欠缺的程式碼,並且通過自動測試
* 確保儘可能少的指令,可用 `$ gcc -S bits.c` 輸出組合語言並觀察 `bits.s` 的程式碼裡頭的 x86 (IA32) 指令
* 避免用分支 (branch),設計時間複雜度為 $O(1)$ 的實作
* 選出其中 7 個位元操作的函式,詳細解釋其原理,需要比照 [clz 應用](https://hackmd.io/s/Bk-uxCYxz) 和 [bit-reverse](https://hackmd.io/s/ByzoiggIb) 的分析方式,==舉出真實世界中的應用案例== (最好在 GitHub 找出程式碼),解說應搭配有效的測試程式碼
* 探討讓 [datalab](https://github.com/sysprog21/datalab) 得以 64-bit friendly 的提案,並舉出實際程式碼修改
## 事前準備
- 詳細閱讀 CMU CS:APP [Data Lab](http://csapp.cs.cmu.edu/3e/datalab.pdf) 要求
- [Bit-wise operations](https://hackmd.io/s/By0MltO_m)
- [bit-field](https://hackmd.io/s/SJ8y82ZYQ)
- [以位元駕馭能量](https://hackmd.io/s/rk2RO0cYX)
- [CS:APP 第 2 章重點提示和練習](https://hackmd.io/s/rJoxSsiuG)
## Coding
- 跟往常一樣,先 fork 到自己的 github 再 clone 下來
- clone 完先 make 一次看看,卻出現錯誤
```c
forest@pop-os:~/datalab$ make btest
gcc -O0 -g -Wall -Werror -m32 -lm -o btest bits.c btest.c decl.c tests.c
In file included from btest.c:17:0:
/usr/include/stdio.h:27:10: fatal error: bits/libc-header-start.h: 沒有此一檔案或目錄
#include <bits/libc-header-start.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
In file included from decl.c:1:0:
/usr/include/stdio.h:27:10: fatal error: bits/libc-header-start.h: 沒有此一檔案或目錄
#include <bits/libc-header-start.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
In file included from /usr/lib/gcc/x86_64-linux-gnu/7/include-fixed/limits.h:194:0,
from /usr/lib/gcc/x86_64-linux-gnu/7/include-fixed/syslimits.h:7,
from /usr/lib/gcc/x86_64-linux-gnu/7/include-fixed/limits.h:34,
from tests.c:3:
/usr/include/limits.h:26:10: fatal error: bits/libc-header-start.h: 沒有此一檔案或目錄
#include <bits/libc-header-start.h>
^~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
Makefile:13: recipe for target 'btest' failed
make: *** [btest] Error 1
```
- 查詢後發現需要安裝 gcc-multilib:
```c
forest@pop-os:~/datalab$ sudo apt-get install gcc-multilib
```
- 之後就能正常編譯了
```c
forest@pop-os:~/datalab$ make btest
gcc -O0 -g -Wall -Werror -m32 -lm -o btest bits.c btest.c decl.c tests.c
```
```c
forest@pop-os:~/datalab$ make check
……
...Gives 42[0x2a]. Should be -1[0xffffffff]
ERROR: Test upperBits(0[0x0]) failed...
...Gives 42[0x2a]. Should be 0[0x0]
Total points: 0/228
```
### absVal
**功能**: 絕對值
**想法**: 這題之前考試出過,作業4( assement )裡也詳細探討過了,所以直接附上[連結](https://hackmd.io/s/B1gN1hBoX#%E6%83%B3%E6%B3%95%EF%BC%9A),差別在於這邊連 `-` 也不能用,所以這邊要對 y 取 2's complement
```c
int absVal(int x)
{
int y = x >> 31;
return (x ^ y) + (~y + 1);
}
```
### addOK
**功能**: 判斷兩數相加是否產生 overflow
**想法**: 兩數 x, y 相加,考慮以下四種狀況
1. 正 + 正
2. 正 + 負
3. 負 + 正
4. 負 + 負
其中 2 跟 3 必不會產生 overflow , 所以只要判斷 1 跟 4,當相加後的值與 x,y ==異號== 則為 overflow ( i.e 正+正= 負 or 負+負= 正 )
```c
int addOK(int x, int y)
{
int x_s = x >> 31;
int y_s = y >> 31;
int xy_s = (x + y) >> 31;
return (((x_s ^ y_s) & 1) | (~((x_s & y_s) ^ xy_s) & 1));
}
```
### allEvenBits
**功能**: 檢查是否所有偶數位元皆為1
**想法**: 因為只看偶數位元,所以奇數位元都設為0,然後確認是否每個偶數位元都等於1
```c
int allEvenBits(int x)
{
x = x & (x >> 2);
x = x & (x >> 4);
x = x & (x >> 8);
x = x & (x >> 16);
return x & 1;
}
```
### allOddBits
**功能**: 檢查是否所有奇數位元皆為1
**想法**: 跟上一個差不多,只是改成把偶數位元設為0
```c
int allOddBits(int x)
{
x = x & (x >> 2);
x = x & (x >> 4);
x = x & (x >> 8);
x = x & (x >> 16);
x = x >> 1;
return x & 1;
}
```
### anyEvenBit
**功能**: 檢查是否有任何偶數位元為1
**想法**: 一樣先將奇數 bit 設為0,只有偶數 bit 皆為0的狀況,輸出才為0
```c
int anyEvenBit(int x)
{
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >> 16);
return x & 1;
}
```
### anyOddBit
**功能**: 檢查是否有任何奇數位元為1
**想法**: 觀念同上一個
```c
int anyOddBit(int x)
{
x = x | (x >> 2);
x = x | (x >> 4);
x = x | (x >> 8);
x = x | (x >> 16);
x = x >> 1;
return x & 1;
}
```
### bang
**功能**: 不使用 `!` 完成 !x 運算
**想法**: `!` 讓非 0 值都變成 0 ,讓 0 變成 1 ,所以重點是確認這個值是否為 0 ,當一個數反向再 1 ,只有 0 會變回 0
```c
int bang(int x)
{
return (1 & (1 ^ ((x | (~x + 1)) >> 31)));
}
```
### bitAnd
**功能**: 用 `~`和`|`完成 and 運算
**想法**: De Morgan's laws : $x.y$ $=$ $\overline{\overline{x.y}}$ $=$ $\overline{\overline{x}+\overline{y}}$
```c
int bitAnd(int x, int y)
{
return ~((~x) | (~y));
}
```
### bitCount
**功能**: 計算 x 中有幾個 1
**想法**: 運用 divide and conquer 的概念,先將 x 切成 32 塊,相鄰的 bit 兩兩相加,重複這個動作直到所有 bits 都加到一塊,即可得到答案,以 8 bit 為例,我做了一個表格來幫助理解:
假設 `x = abcdefgh` 為一個 8 bit 整數,一開始用 `0x5555` 當 mask 是為了讓相鄰兩個 bit 相加, `x & mask1` 得到 odd bits b,d,f,h , `(x >> 1) & mask1` 得到 even bits a,c,e,g ,將兩者相加得到 `a+b, c+d, e+f, g+h` ( 圖中省略`+` ),以此類推,最後可以得到 `a+b+c+d+e+f+g+h` ,同理,32 bit 也可以做出來,最後 `& 0x3f` 是因為 ans 最大只有 32
![](https://i.imgur.com/FZEQEbv.png)
```c
int bitCount(int x)
{
int mask1 = 0x55;
int mask2 = 0x33;
int mask3 = 0x0f;
mask1 |= mask1 << 8;
mask1 |= mask1 << 16;
mask2 |= mask2 << 8;
mask2 |= mask2 << 16;
mask3 |= mask3 << 8;
mask3 |= mask3 << 16;
int ans = (x & mask1) + ((x >> 1) & mask1);
ans = (ans & mask2) + ((ans >> 2) & mask2);
ans = (ans & mask3) + ((ans >> 4) & mask3);
return (ans + (ans >> 8) + (ans >> 16) + (ans >> 24)) & 0x3f;
}
```
### bitMask
**功能**: 介於(包含) highbit 與 lowbit 之間的 bits 設為 1
**想法**: highbit 之下、 lowbit 之上的 bits 設成1,再 and 運算
```c
int bitMask(int highbit, int lowbit)
{
int hi = ~((-1) << highbit << 1);
int lo = ~((1 << lowbit) - 1);
return hi & lo;
}
```
### bitMatch
**功能**: x == y ? 1:0
**想法**: xnor 運算:相同為1,不同為0, De Morgan’s laws
```c
int bitMatch(int x, int y)
{
return ~(~x & y) & ~(x & ~y);
}
```
### bitNor
**功能**: nor 運算
**想法**: De Morgan’s laws
```c
int bitNor(int x, int y)
{
return ~x & ~y;
}
```
### bitOr
**功能**: or 運算
**想法**: De Morgan’s laws
```c
int bitOr(int x, int y)
{
return ~(~x & ~y);
}
```
### bitParity
**功能**: 同位元檢查,奇數個 0(1) 回傳 1,偶數個 0(1) 回傳 0
**想法**: 透過 xor 運算就能得知, e.g
x = 1010 ,則 1 ^ 0 ^ 1 ^ 0 = 0
x = 1011 ,則 1 ^ 0 ^ 1 ^ 1 = 1
所以只要將所有 bits 都 xor 過一次就是答案
```c
int bitParity(int x)
{
x ^= x >> 16;
x ^= x >> 8;
x ^= x >> 4;
x ^= x >> 2;
x ^= x >> 1;
return x & 1;
}
```
### bitReverse
**功能**: reverse the bits
**想法**: 一開始 2bits 之間互換,再來 4bits 之間互換,之後繼續 double 互換區塊的 size ,最後就能得到答案,以 8 bits 為例:
|[a] | [b] |[c]| [d]|[e] |[f]|[g] |[h]|
|-|-|-|-|-|-|-|-|
|[b |a] |[d |c ]|[f| e ]|[h| g]|
|[d |c |b |a ]|[h |g|f |e ]|
|[h |g |f |e |d |c |b |a ]|
```c
int bitReverse(int x)
{
int mask1 = 0x55;
int mask2 = 0x33;
int mask3 = 0x0f;
int mask4 = 0x00ff;
int mask5 = 0xff;
mask1 |= mask1 << 8;
mask1 |= mask1 << 16;
mask2 |= mask2 << 8;
mask2 |= mask2 << 16;
mask3 |= mask3 << 8;
mask3 |= mask3 << 16;
mask4 |= mask4 << 16;
mask5 |= mask5 << 8;
x = ((x >> 1) & mask1) | ((x & mask1) << 1);
x = ((x >> 2) & mask2) | ((x & mask2) << 2);
x = ((x >> 4) & mask3) | ((x & mask3) << 4);
x = ((x >> 8) & mask4) | ((x & mask4) << 8);
x = ((x >> 16) & mask5) | ((x & mask5) << 16);
return x;
}
```
### bitXor
**功能**: xor
**想法**: De Morgan’s laws
$x \oplus y$ $=$ $\overline{x}y + x\overline{y}$ $=$ $\overline{\overline{\overline{x}y} . \overline{x\overline{y}}}$
```c
int bitXor(int x, int y)
{
return ~(~(~x & y) & ~(x & ~y));
}
```
### bitSwap
**功能**: 將指定的 bytes 互換
**想法**: 因為是交換一個 byte ,所以一次位移的量是 8 的倍數,先將要互換的兩個 byte 分別移到最低位元組,將兩數 xor 可以得到一個 mask ,用這個 mask 跟那兩數再作一次 xor 即可得到另外一數, e.g
假設要互換的 byte 為 A、C
則 $xor$ = $A \oplus C$
$xor \oplus A$ = $C$
$xor \oplus C$ = $A$
運用這個原理就能將兩個 bytes 互換,且不影響其他 bytes
```c
int byteSwap(int x, int n, int m)
{
int set1 = (x >> (n << 3)) & 0xff;
int set2 = (x >> (m << 3)) & 0xff;
int xor = (set1 ^ set2);
xor = (xor << (n << 3)) | (xor << (m << 3));
return x ^ xor;
}
```
### conditional
**功能**: x ? y : z
**想法**: 只有當 x = 0 時,x = z,所以只要區分 0 和 非0 的值即可
```c
int conditional(int x, int y, int z)
{
int s = (!!x - 1) & (-1);
return (y & (-1-s)) | (z & (s));
}
```
### countLeadingZero
**功能**: 計算 x 之 leading zero 個數
**想法**:
```c
int countLeadingZero(int x)
{
int mask1 = 0x55;
int mask2 = 0x33;
int mask3 = 0x0f;
mask1 |= mask1 << 8;
mask1 |= mask1 << 16;
mask2 |= mask2 << 8;
mask2 |= mask2 << 16;
mask3 |= mask3 << 8;
mask3 |= mask3 << 16;
x = x | (x >> 16);
x = x | (x >> 8);
x = x | (x >> 4);
x = x | (x >> 2);
x = x | (x >> 1);
// bitCount
int ans = (x & mask1) + ((x >> 1) & mask1);
ans = (ans & mask2) + ((ans >> 2) & mask2);
ans = (ans & mask3) + ((ans >> 4) & mask3);
return 32 - ((ans + (ans >> 8) + (ans >> 16) + (ans >> 24)) & 0x3f);
}
```
### copyLSB
**功能**: 將所有 bits 變成 LSB
**想法**:
```c
int copyLSB(int x)
{
int s = x & 0x1;
return !s - 1;
}
```
### distinctNegation
**功能**: 判斷 x 是否等於 -x
**想法**:
```c
int distinctNegation(int x)
{
x = x << 1;
return !(!x);
}
```
### dividePower2
**功能**: 計算 x / (2^n)
**想法**:
```c
int dividePower2(int x, int n)
{
int s = x >> 30 >> 1;
return (x + (((1 << n) - 1) & s)) >> n;
}
```
### evenBits
**功能**: 所有偶數 bit 設為 1
**想法**:
```c
int evenBits(void)
{
int x = 0x55;
x |= x << 8;
x |= x << 16;
return x;
}
```
### ezThreeFourths
**功能**: x 乘 3/4
**想法**:
```c
int ezThreeFourths(int x)
{
x = x + (x << 1);
return (x + ((x >> 30 >> 1) & 3)) >> 2;
}
```
### fitsBits
**功能**: 判斷 x 能否用 n-bit 2的補數表示
**想法**:
```c
int fitsBits(int x, int n)
{
int mask = 32 + (~n + 1);
return !(x ^ (x << mask >> mask));
}
```
### fitsShort
**功能**: 判斷 x 能否用 16-bit 2的補數表示
**想法**:
```c
int fitsShort(int x)
{
return !(x ^ (x << 16 >> 16));
}
```
### floatAbsVal
**功能**: 取 floating point f 的絕對值
**想法**:
```c
unsigned floatAbsVal(unsigned uf)
{
unsigned ma = uf & 0x007fffff;
unsigned ex = (uf & 0x7f800000);
return (ex == 0x7f800000 && ma) ? uf : (0x7fffffff & uf);
}
```
### floatFloat2Int
**功能**: (int)f
**想法**:
```c
int floatFloat2Int(unsigned uf)
{
unsigned s = (uf & 0x80000000) >> 31;
unsigned ma = (uf & 0x007fffff) | 0x00800000;
int ex = (((uf & 0x7f800000) >> 23) - 127);
unsigned ans;
if (ex < 0)
return 0;
else if (ex > 31)
return 0x80000000u;
if (ex < 23)
ans = ma >> (23 - ex);
else
ans = ma << (ex - 23);
if (s)
return ~ans + 1;
return ans;
}
```
### floatInt2Float
**功能**: (float)x
**想法**:
```c
unsigned floatInt2Float(int x)
{
int s = x&0x80000000;
int exp = -1;
int ma = 0;
if (!x)
return 0;
else if (x==0x80000000)
return 0xcf000000;
if (s) x=~x+1;
//ma = x;
while(x) {
x >>= 2;
exp++;
}
if (exp <= 23) {
ma = x;
exp <<= 23;
}
else {
}
return s | exp | ma;
}
```
### floatIsEqual
**功能**: f==g
**想法**:
```c
int floatIsEqual(unsigned uf, unsigned ug)
{
int mask_us = 0x7fffffff;
int exmask = 0x7f800000;
int isNaN = ((uf & mask_us) > exmask || (ug & mask_us) > exmask);
int zeros = (!((uf & mask_us) || ((ug & mask_us))));
return (!isNaN) && (zeros || (uf == ug));
}
```
### floatIsLess
**功能**: f < g
**想法**:
```c
int floatIsLess(unsigned uf, unsigned ug)
{
int mask_us = 0x7fffffff;
int exmask = 0x7f800000;
int mamask = 0x007fffff;
int uf_s = (uf >> 31) & 1, ug_s = (ug >> 31) & 1;
int uf_ex = (uf >> 23) & 0xff, ug_ex = (ug >> 23) & 0xff;
int uf_ma = (uf & mamask), ug_ma = (ug & mamask);
int isNaN = ((uf & mask_us) > exmask || (ug & mask_us) > exmask);
if (!(uf & mask_us) && !(ug & mask_us))
return 0;
if (isNaN)
return 0;
if (uf_s ^ ug_s)
return uf_s > ug_s;
if (uf_ex ^ ug_ex)
return (uf_ex < ug_ex) ^ uf_s;
if (uf_ma ^ ug_ma)
return (uf_ma < ug_ma) ^ uf_s;
return 0;
}
```
### floatNegate
**功能**: -f
**想法**:
```c
unsigned floatNegate(unsigned uf)
{
if ((uf & 0x7fffffff) > 0x7f800000)
return uf;
return uf ^ 0x80000000;
}
```
### floatPower2
**功能**: 2.0 ^ x
**想法**:
```c
unsigned floatPower2(int x)
{
unsigned INF = 0xff << 23;
int e = 127 + x;
if (x < 0)
return 0;
if (e >= 255)
return INF;
return e << 23;
}
```
### floatScale1d2
**功能**: 0.5 * f
**想法**:
```c
unsigned floatScale1d2(unsigned uf)
{
unsigned s = uf & 0x80000000;
unsigned ex = uf & 0x7f800000;
if (ex >= 0x7f800000)
return uf;
ex >>= 23;
if (ex <= 1) {
if ((uf & 3) == 3)
uf += 2;
return s | ((uf >> 1) & 0x007fffff);
}
return (uf & 0x807fffff) | ((ex - 1) << 23);
}
```
### floatScale2
**功能**: 2 * f
**想法**:
```c
unsigned floatScale2(unsigned uf)
{
unsigned s = uf & 0x80000000;
unsigned ex = uf & 0x7f800000;
if (ex == 0x7f800000)
return uf;
if (ex == 0)
return s | (uf << 1);
ex += (1 << 23);
if (ex == 0x7f800000)
return s | 0x7f800000;
return (uf & 0x807fffff) | ex;
}
```
### floatScale64
**功能**: 64 * f
**想法**:
```c
unsigned floatScale64(unsigned uf)
{
int exp = (uf & 0x7F800000) >> 23;
int sign = uf & 0x80000000;
int cnt = 22;
if (exp == 0) {
if (!(uf & 0x007E0000))
return (uf << 6) | sign;
while (!(uf & (1 << cnt)))
cnt--;
uf <<= (23 - cnt);
return sign | (uf & 0x807FFFFF) | ((cnt - 16) << 23);
}
if (exp == 255)
return uf;
exp += 6;
if (exp >= 255)
return 0x7F800000 | sign;
return (uf & 0x807FFFFF) | (exp << 23);
}
```
### floatUnsigned2Float
**功能**: (float)u
**想法**:
```c
unsigned floatUnsigned2Float(unsigned u)
{
int i = 1;
unsigned temp;
unsigned result;
if (u == 0) {
return 0;
}
while ((u & 0x80000000) != 0x80000000) {
++i;
u <<= 1;
}
result = u << 1;
temp = result;
result >>= 9;
result &= 0x7fffffff;
i = (32 - i) + 127;
result = (result & 0x807FFFFF) | (i << 23);
if ((temp & 0x00000100) == 0x00000100) {
if (temp & 0x000000FF) {
return result + 1;
} else {
if (result & 1) {
return result + 1;
} else {
return result;
}
}
}
return result;
}
```
### getByte
**功能**: 取出 x 的第 n byte
**想法**:
```c
int getByte(int x, int n)
{
x = x >> (n << 3);
return x & 0xff;
}
```
### greatestBitPos
**功能**:
**想法**:
```c
int greatestBitPos(int x)
{
int n = 0;
n += ((!!(x & ((~0) << (n + 16)))) << 4);
n += ((!!(x & ((~0) << (n + 8)))) << 3);
n += ((!!(x & ((~0) << (n + 4)))) << 2);
n += ((!!(x & ((~0) << (n + 2)))) << 1);
n += (!!(x & ((~0) << (n + 1))));
return (1 << n) & x;
}
```
### howManyBits
**功能**: 回傳表示 x 所需的最少 bits 數
**想法**:
```c
int howManyBits(int x)
{
int sign, bit0, bit1, bit2, bit4, bit8, bit16;
sign = x >> 30 >> 1;
x = (sign & ~x) | (~sign & x);
bit16 = !!(x >> 16) << 4;
x = x >> bit16;
bit8 = !!(x >> 8) << 3;
x = x >> bit8;
bit4 = !!(x >> 4) << 2;
x = x >> bit4;
bit2 = !!(x >> 2) << 1;
x = x >> bit2;
bit1 = !!(x >> 1);
x = x >> bit1;
bit0 = x;
return bit16 + bit8 + bit4 + bit2 + bit1 + bit0 + 1;
}
```
### implication
**功能**: x -> y in propositional logic
**想法**: 只有當 x=1,y=0 時才為 false
```c
int implication(int x, int y)
{
return (!x) | y;
}
```
### intLog2
**功能**: floor(log base 2 of x)
**想法**:
```c
int intLog2(int x)
{
int a0 = 0xFF | (0xFF << 8);
int a1 = a0 ^ (a0 << 8);
int a2 = a1 ^ (a1 << 4);
int a3 = a2 ^ (a2 << 2);
int a4 = a3 ^ (a3 << 1);
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
x = (x & a4) + ((x >> 1) & a4);
x = (x & a3) + ((x >> 2) & a3);
x = (x & a2) + ((x >> 4) & a2);
x = (x & a1) + ((x >> 8) & a1);
x = (x & a0) + ((x >> 16) & a0);
return x + ~0;
}
```
### isAsciiDigit
**功能**: return 1 if 0x30 <= x <= 0x39 (ASCII codes for characters '0' to '9')
**想法**:
```c
int isAsciiDigit(int x)
{
return !(((!!((x >> 4) ^ 3)) | (x >> 3 & x >> 1) | (x >> 3 & x >> 2)) & 1);
}
```
### isEqual
**功能**: 判斷 x == y
**想法**:
```c
int isEqual(int x, int y)
{
return !(x ^ y);
}
```
### isGreater
**功能**: x > y
**想法**:
```c
int isGreater(int x, int y)
{
int sign = ((~x & y) >> 31) & 1;
int mark = ~((x ^ y) >> 31);
int NotEqul = !!(x ^ y);
return sign | ((mark) & (~(x + (~y + 1)) >> 31) & NotEqul);
}
```
### isLess
**功能**: x < y
**想法**:
```c
int isLess(int x, int y)
{
int sign = ((x & ~y) >> 31) & 1;
int mark = ~((x ^ y) >> 31);
return sign | (((mark) & (x + (~y + 1)) >> 31) & 1);
}
```
### isLessOrEqual
**功能**: x <= y
**想法**:
```c
int isLessOrEqual(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) & 1);
}
```
### isNegative
**功能**: x < 0
**想法**:
```c
int isNegative(int x)
{
int sign = x >> 31;
return !!sign;
}
```
### isNonNegative
**功能**: x >= 0
**想法**:
```c
int isNonNegative(int x)
{
int sign = x >> 31;
return !sign;
}
```
### isNonZero
**功能**: 不使用 ! 判斷 x 是否為非 0 值
**想法**:
```c
int isNonZero(int x)
{
int ans = (1 & (1 & ((x | (~x + 1)) >> 31)));
return ans;
}
```
### isNotEqual
**功能**: return 0 if x == y, and 1 otherwise
**想法**: XOR
```c
int isNotEqual(int x, int y)
{
return !!(x ^ y);
}
```
### isPallindrome
**功能**: Return 1 if bit pattern in x is equal to its mirror image
**想法**:
```c
int isPallindrome(int x)
{
int x_ = x;
int a0 = 0xFF | (0xFF << 8);
int a1 = a0 ^ (a0 << 8);
int a2 = a1 ^ (a1 << 4);
int a3 = a2 ^ (a2 << 2);
int a4 = a3 ^ (a3 << 1);
x_ = (x_ << 16) | ((x_ >> 16) & a0);
x_ = ((x_ & a1) << 8) | ((x_ >> 8) & a1);
x_ = ((x_ & a2) << 4) | ((x_ >> 4) & a2);
x_ = ((x_ & a3) << 2) | ((x_ >> 2) & a3);
x_ = ((x_ & a4) << 1) | ((x_ >> 1) & a4);
return !(x ^ x_);
}
```
### isPositive
**功能**: x > 0
**想法**:
```c
int isPositive(int x)
{
int sign = x >> 31;
return (!sign & !!x);
}
```
### isPower2
**功能**: 判斷 x 是否為 power of 2
**想法**:
```c
int isPower2(int x)
{
int minus_noe = (~0 ^ (x >> 31));
return !((x & (x + minus_noe)) | !x);
}
```
### isTmax
**功能**: 判斷 x 是否為最大值
**想法**:
```c
int isTmax(int x)
{
x += 1;
return (!!x & !(x ^ (~x + 1)));
}
```
### isTmin
**功能**: 判斷 x 是否為最小值
**想法**:
```c
int isTmin(int x)
{
return (!!x & !(x ^ (~x + 1)));
}
```
### isZero
**功能**: x==0
**想法**:
```c
int isZero(int x)
{
return !x;
}
```
### leastBitPos
**功能**: return a mask that marks the position of the least significant 1 bit. If x == 0, return 0
**想法**:
```c
int leastBitPos(int x)
{
return x & (~x + 1);
}
```
### leftBitCount
**功能**: returns count of number of consective 1's in left-hand (most significant) end of word.
**想法**:
```c
int leftBitCount(int x)
{
int a0 = 0xFF | (0xFF << 8);
int a1 = a0 ^ (a0 << 8);
int a2 = a1 ^ (a1 << 4);
int a3 = a2 ^ (a2 << 2);
int a4 = a3 ^ (a3 << 1);
x = ~x;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
x = ~x;
x = (x & a4) + ((x >> 1) & a4);
x = (x & a3) + ((x >> 2) & a3);
x = (x & a2) + ((x >> 4) & a2);
x = (x & a1) + ((x >> 8) & a1);
x = (x & a0) + ((x >> 16) & a0);
return x;
}
```
### logicalNeg
**功能**: implement the ! operator
**想法**:
```c
int logicalNeg(int x)
{
int ans = (1 & (1 ^ ((x | (~x + 1)) >> 31)));
return ans;
}
```
### logicalShift
**功能**: shift x to the right by n, using a logical shift
**想法**:
```c
int logicalShift(int x, int n)
{
return (x >> n) & ~(((1 << 30 << 1) >> n) << 1);
}
```
### maximumOfTwo
**功能**: compute the maximum of two integers without branching
**想法**:
```c
int maximumOfTwo(int x, int y)
{
int delta = x - y;
int neg = delta >> 31;
int max = (~neg & x) | (neg & y);
int alien = (x ^ y) >> 31;
int x_pos = ~(x >> 31);
return (~alien & max) | (alien & x_pos & x) | (alien & ~x_pos & y);
}
```
### minusOne
**功能**: return -1
**想法**:
```c
int minusOne(void)
{
return ~0;
}
```
### multFiveEighths
**功能**: multiplies by 5/8 rounding toward 0
**想法**:
```c
int multFiveEighths(int x)
{
x = x + (x << 2);
return (x + ((x >> 30 >> 1) & 7)) >> 3;
}
```
### negate
**功能**: return -x
**想法**:
```c
int negate(int x)
{
return ~x + 1;
}
```
### oddBits
**功能**: return word with all odd-numbered bits set to 1
**想法**:
```c
int oddBits(void)
{
int ans = 0xaaaa;
ans |= ans << 16;
return ans;
}
```
### remainderPower2
**功能**:
**想法**:
```c
int remainderPower2(int x, int n)
{
int sign = x >> 31;
int pos = x + (~((x >> n) << n) + 1);
int neg;
x = ~x + 1;
neg = x + (~((x >> n) << n) + 1);
neg = ~neg + 1;
return (~sign & pos) | (sign & neg);
}
```
### replaceByte
**功能**: Replace byte n in x with c
**想法**:
```c
int replaceByte(int x, int n, int c)
{
int mask = 0xFF << (n << 3);
return (mask & (c << (n << 3))) | (~mask & x);
}
```
### rotateLeft
**功能**: Rotate x to the left by n
**想法**:
```c
```
### rotateRight
**功能**: Rotate x to the right by n
**想法**:
```c
```
### satAdd
**功能**: adds two numbers but when positive overflow occurs, returns maximum possible value, and when negative overflow occurs, it returns minimum positive value.
**想法**:
```c
```
### satMul2
**功能**: multiplies by 2, saturating to Tmin or Tmax if overflow
**想法**:
```c
```
### satMul3
**功能**: multiplies by 3, saturating to Tmin or Tmax if overflow
**想法**:
```c
```
### sign
**功能**: return 1 if positive, 0 if zero, and -1 if negative
**想法**:
```c
int sign(int x)
{
return (x >> 31) | (!!x);
}
```
### signMag2TwosComp
**功能**: Convert from sign-magnitude to two's complement where the MSB is the sign bit
**想法**:
```c
int signMag2TwosComp(int x)
{
int sign = x >> 31;
int mag = x & ~(1 << 31);
return (sign & (~mag + 1)) | (~sign & mag);
}
```
### specialBits
**功能**: return bit pattern 0xffca3fff
**想法**:
```c
int specialBits(void)
{
return ~(0xd7 << 14);
}
```
### subtractionOK
**功能**:Determine if can compute x-y without overflow
**想法**:
```c
int subtractionOK(int x, int y)
{
int s_xy = !!((x >> 31) ^ (y >> 31));
int s_y = !(((x - y) >> 31) ^ (y >> 31));
return !(s_xy & s_y);
}
```
### thirdBits
**功能**: return word with every third bit (starting from the LSB)
**想法**:
```c
int thirdBits(void)
{
int x = 0x49;
x |= (x << 9);
x |= (x << 18);
return x;
}
```
### tmax
**功能**: return maximum two's complement integer
**想法**:
```c
int tmax(void)
{
return ~(1 << 31);
}
```
### tmin
**功能**: return minimum two's complement integer
**想法**:
```c
int tmin(void)
{
return 1 << 31;
}
```
### trueFiveEighths
**功能**: multiplies by 5/8 rounding toward 0, avoiding errors due to overflow
**想法**:
```c
int trueFiveEighths(int x)
{
int eights = x >> 3;
int rem = x & 7;
return eights + (eights << 2) + ((rem + (rem << 2) + (x >> 30 >> 1 & 7)) >> 3);
}
```
### trueThreeFourths
**功能**: multiplies by 3/4 rounding toward 0, avoiding errors due to overflow
**想法**:
```c
int trueThreeFourths(int x)
{
int const four = x >> 2;
int const rem = x & 3;
return four + (four << 1) + ((rem + (rem << 1) + (x >> 31 & 3)) >> 2);
}
```
### twosComp2SignMag
**功能**: Convert from two's complement to sign-magnitude
**想法**:
```c
int twosComp2SignMag(int x)
{
int sign = x >> 31;
int mag = (sign & (~x + 1)) | (~sign & x);
return (sign & (1 << 31)) | mag;
}
```
### upperBits
**功能**: pads n upper bits with 1's
**想法**:
```c
int upperBits(int n)
{
int not = !n;
int zero = ~not + 1;
return ~zero & ((1 << 31) >> (n + (~0)));
}
```
:::info
目前進度: 215/228
:::