1. Int 在計算機中占 4 Byte, 共 32 位, 最大正數為 2147483647, 最小負數為 -2147483648
2. 正數存儲在計算機中的形式為原碼,最大正數的十六進制形式為 0X7FFFFFFF. 第一位為7, 二進制位 0111, 最高位為符號位, 所以正數的最高位為0
3. 負數在計算機的存儲形式為補碼, 最小負數為0XFFFFFFFF, 第一位是F, 二進制為 1111, 負數的最高位是1
4. 大學時變反加一背的滾瓜爛熟, -x 可以通過 x 的二進制取反加一最高位置 1 獲得
5. 溢出. 0X7FFFFFFF + 1 == 0X80000000, 由最大正數變成最小負數
Leetcode StringToInteger
主要考察溢出處理, 我在處理溢出時用了很多的判斷語句, 寫的甚是不雅
int atoi(const char *str) { if(!strlen(str)) return 0; bool neg = false; int cur = 0; int res = 0, num=0; while(str[cur] == ' ') cur++; if(str[cur]=='-') { neg = true; cur++; } else if(str[cur]=='+') { cur++; }else{} while(isNum(str[cur], num)) { if( MAXN/10 > res) { res = res * 10 + num; }else if( MAXN/10 == res) { if(neg) { if(num >=8) return MINN; else res = res * 10 + num; }else{ if(num>=7) return MAXN; else res = res * 10 + num; } }else{ if(neg) return MINN; else return MAXN; } cur++; } if(neg) return (-1)*res; else return res; }
LeetCode SingleNumberII
1. 先假設所求是正數, 將二進制看出正數的原碼表示
2. 假如最高位是 1, 說明所求數字實際為負數, 那么我們對 res 減一變反, 得到所求數字的絕對值再乘以 -1 即可
3. 注意, 對二進制進行操作和對十進制操作是等價的, 在這個地方想了很久. 因為變量 res 實際上只是以十進制的形式存下了二進制的數據, 當所求數字為正數時, 萬事大吉, res 即為所求. 當所求為負數時, 那么 res 是沒有意義的, 只是簡單的用十進制形式存了某個二進制的數, 我們對其進行位操作, 減一, 求反. 得到其絕對值都相當於直接對二進制進行操作
4. 細節. 對二進制求反可以直接異或 0X11111111
for(int i = 30; i >= 0; i --) { res = res*2 + (record[i]%3); } // 負數, 按位取反, 末尾加一的逆過程 if( record[31] %3 ) { res = (res - 1)^(0x7FFFFFFF); res = -1 * res; }