一.二進制與進制轉化
1.概念解析
我們常常能聽見2進制,8進制,16進制這些講法。他們都是數值的不同表達形式。根據不同的進制大小有著不同的權重比例。我們生活中常用的是10進制數,也就是逢10進1,由此推理至其他進制。例如2進制就是逢2進1。
2.進制轉化
(1)10進制轉化為2進制
如圖將10進制的數不斷對進制數進行取模,之后在將數除等原數,周而復始,最后將輸出數導致就是原數轉換的進制數。
?(2)2進制轉8進制
8進制中每一位都是0~7中的數字,0~7的數字各自寫成2進制位最多有3個就足夠了。所以我們將二進制位轉換時,每次只需3位3位的進行轉化。
(3)2進制轉16進制
與上文同理,16進制位是由0~9,A~F直接的數組成的,用2進制表示最多只有4位。
?3.相關技巧與用法
例如給定x進制,x進制形式的數s,要將其轉換為z進制形式。
思路為先將x進制的數s轉化為10進制形式,再將該數轉化為z進制形式。
將x進制的s轉化為10進制形式有兩種方法:
(1)逐位相乘法
int main()
{int x;int i = 0;string s;int ret = 0;cin >> x >> s;int n = s.size() - 1;while (n >= 0){if (s[n] <= '9'){ret += (s[n--] - '0') * pow(x, i);}else{ret += (s[n--] - 'A' + 10) * pow(x, i);}i++;}cout << ret;return 0;
}
將每一位的數乘對應的權重轉化為10進制相加。
(2)庫函數調用
#include <string>
int main()
{int x;string s;cin >> x >> s;int ret = stoi(s, nullptr, x);cout << ret;return 0;
}
這里調用了stoi函數(string? to? int),將字符串轉換為int形式,有三個參數,stoi(const string& str, size_t* idx = 0, int base = 10);
。第一個參數為需要轉化的字符串,第二個是一個指針,指向停止轉化的字符;第三個參數是需要轉換的進制(默認情況為10進制)。
在這里我們將字符串s轉化為x進制。
(3)將10進制轉化為z進制
string s = "0123456789ABCDEF";void print(int ret, int m)
{if (ret > m){print(ret / m, m);}cout << s[ret % m];
}
這里我們將10進制數設置為ret,需要轉換的進制為m進制。我們使用一個遞歸,參照上面的(10進制轉化為2進制的思路)。
二.位運算
1.概念解析
這里就做一些簡單的介紹,重點內容在于后序的運用方法。
(1)左移右移操作符
最高的符號位不變,左移將二進制數整體左移動一位右邊補0;右移將二進制整體右移一位,此時分為兩種情況。如果是邏輯右移則左邊用0進行填充,若是算術右移則左邊用符號位進行填充。
(2)&(按位與)? |(按位或)? ^(按位異或)? ~(按位取反)
例a&b當a與b二進制位上都為1,得到的結果為1,否則為0。
例a|b當a與b二進制位上有1則為1,否則為0。
例a^b當a與b二進制位上相同則為0,不相同則為1。
例~a,將1變為0,將0變為1。
這里有個小tips:
所有的二進制操作都是先轉化為補碼的形式展開的,正數的原碼反碼補碼都相同,負數將原碼取反加1(符號位不變)得到的就是補碼。
2.位運算的應用
(1)保留二進制位中的指定位
?有時候我們希望取出二進制中的某一位,使其他位變為0。我們只需要將對應的位進行(x&m)處理。
?(2)獲取二進制中的指定位

(3)將指定二進制位設置為1

?(4)將指定二進制位設置為0
我們需要對指定位置設置為0,只需要對該位進行&1處理,而其他位需要&0處理。所以我們先將1移動到要置為0的位置,再按位取反,這樣就只有該位得到0其余位都為1。
?
(5)反轉指定二進制位
使用一個數m,使得m的二進制位中的第i位為1其余設置為0,然后將(x^m)得到反轉后的值。
由于按位取反中,若原數第i位為1,相同異或取反后變為0,若原數為0,與1異或取反后為1。
?(6)將二進制位最右邊的1變為0
我們可以使用x? &(x-1)的方法x - 1讓有1的最低的一位變為了0,而其他位不會改變。將其進行&,就可以消去最右邊的那一位1。
我們可以通過?x? &(x-1)的計算消除一位1,那么如果我們對一個數不斷的進行消除1的操作,套上一個循環,就能計算出這個二進制數中1的個數。
一些其他用途:
這種思路有一個專有名詞叫做位圖(bitmap)。位圖是數據結構操作系統常用的數據結構,他可以高效的快速釋放資源?
(7)只保留二進制位中最右邊的1

(8)異或的巧用
相同的兩個數異或的結果為0;0與任何數x異或的結果為x;同時異或滿足交換律a^b^a == a^a^b;