文章插圖

文章插圖
背景
為什么要做js位運算呢?
因為最近在學習hash算法,里面用到了大量的位運算另外網上也找了很多資料,但大都比較片面,沒有說明特殊情況時的處理,換幾組數據計算結果就出錯 。重溫整數
ECMAScript 整數有兩種類型,即:
有符號整數(允許用正數和負數)無符號整數(只允許用正數) 在 ECMAScript 中,所有整數字面量默認都是有符號整數,這意味著什么呢?
有符號整數使用 31 位表示整數的數值,用第 32 位表示整數的符號,0 表示正數,1 表示負數 。
數值范圍從 -2147483647 到 2147483647 。
位運算會把二進制數限制在32位,超出部分會被舍棄
調試位運算常用的幾個方法toString(2)
轉換成2進制字符串
vara=1732584193;a.toString(2);//1100111010001010010001100000001parseInt(‘11001’, 2)將2進制字符串轉換成10進制數
parseInt('11001',2)//25padStart(32, ‘0’)字符串總長度,左邊不足位數補0
'1100000001'.padStart(32,0)//00000000000000000000001100000001源碼、反碼、補碼源碼將數字轉換成的2進制數, 最左邊表示符號位,1負數,0正數
5 源碼:0101-10源碼:11010反碼正數的反碼與其原碼相同
負數的反碼,除符號位外,其他位取反
5源碼:0101反碼:0101-10源碼:11010反碼:10101補碼正整數的補碼與其原碼相同
負整數的補碼,取反碼+1
5源碼:0101補碼:0101-10源碼:11010補碼:10110ok,現在開始正題位運算符非(~)與(&)或(|)異或(^)帶符號左移(<<)帶符號右移(>>)無符號右移(>>>)位運算符:非(~)
運算步驟:
將該數字取負數然后減1
~25//-26過程:25取負:-25減1:-26
~1//-2~-1//0~100//-101~-100//99位運算符:與(&)運算步驟:
把兩個數轉換成2進制補碼相同位置進行比較(同為1,結果為1,否則為0)如果計算結果是負數,還要再做補碼處理
如果位數不夠,正數左邊補0,負數補1
正正運算
10&3//2過程:10 補碼:10103 補碼:0011結果:0010,即 2正負運算(1)
14&-13//2過程:14 補碼:01110(補一位符號位)-13 源碼:11101,補碼:10011與運算:00010,即 2正負運算(2)
88&-19//72過程:88 補碼:01011000(補一位符號位)-19 源碼:110011,補碼:10110001011000 & 101100負數(101100)位數不夠,左邊補1,即11101100也就是 01011000 & 11101100結果為:01001000,即:72負負運算
-12&-5//-16過程:-12 補碼:10100-5 補碼:11011與運算:10000結果為負,再取一次補碼: 110000:-16練習
3&7-21&16-271733879&-17325841941125899778533470&81293020&0xF48192342&0xFFFF位運算符:或(|)運算步驟:
把兩個數字轉換成2進制補碼相同位置進行比較(有一個是1,結果即為1)如果計算結果是負數,還要再做補碼處理正正運算
10|3//11過程:10 源碼:10103 源碼:0011結果:1011,即 11正負運算
10|-3//-1過程:10補碼:01010-3補碼:11101或運算:11111結果為負,再取碼:10001,即:-1負負運算
-15|-21//-5過程:-15 補碼:110001-21 補碼:101011或運算:111011結果為負再取補碼:10101,即:-5練習
15|2040|-14-271733879|1732584193(-271733879&-1732584194)|(~-271733879&271733878)位運算符:異或(^)運算步驟:
把兩個數轉換成2進制補碼相同位置進行比較(必須是0和1或者1和0,結果才為1)如果結果為負,再取補碼正正異或
10^3//9過程:10 補碼:10103 補碼:0011結果:1001,即 9正負異或
10^-3//-9過程:10 補碼: 01010-3 補碼:11101異或運算:10111結果為負,再取補碼:11001,即-9負負異或
-10^-3//11【js 負數 正數變為負數的函數】過程:-10 補碼:10110-3 補碼:11101異或運算:01011,即:11練習
5^8-10^9-13^-20-271733879^-1732584194^271733878位運算符:帶符號左移(<<)運算步驟:
把數字轉換成2進制補碼左移指定位數,右邊補0如果結果未負數,再取補碼
超過32位的部分舍棄
正數左移
1 << 2 //補碼:00000001 左移2位, 即00000100,結果為:45 << 3 //補碼:00000101 左移3位, 即00101000,結果為:40可以看出,正數帶符號左移,即 a << n,其實是 a * 2的n次冪負數左移
-3<<4-3 補碼:101左移4位 1010000標志位為負,取補碼:1110000,即-48-6 << 3 // 1010<< 3 等于 1010000,取補碼,1110000即:-48-11 << 4 // 10101 << 4 等于 101010000,取補碼,110110000即:-176邊緣情況情況1:正數變負數1732584193<<2//-1659597820計算過程1732584193轉換成2進制源碼:1100111010001010010001100000001(31位)左移2位,補2個0:110011101000101001000110000000100(33位)移除左邊多余的1位:10011101000101001000110000000100(32位)變為負數,取補碼:11100010111010110111001111111100即:-1659597820情況2:負數變正數
-1732584193<<2//1659597820計算過程-1732584193轉換成2進制:11100111010001010010001100000001(32位)負數,取補碼:10011000101110101101110011111111(32位)左移2位:1001100010111010110111001111111100(34位)多余部分舍棄:01100010111010110111001111111100(32位)符號位為正,無需再補碼,即:1659597820練習
1<<321<<331<<402147483648<<21732584193<<6位運算符:帶符號右移(>>)運算步驟:
取數字二進制補碼右移指定位數,左邊補位與符號位一致多余位被舍棄如果計算結果為負,再取補碼正數右移
5>>1//0101右移1位0010,即21>>2//0001右移1位0000,即0正數右移比較簡單,移出的內容直接舍棄即可,左邊用0補充負數右移
-5>>2//-2分析:-5 補碼:1011右移2位:1110結果為負,取補碼:1010,即-2練習
5+64>>91732584193>>4位運算符:無符號右移(>>>)運算步驟:
把數字轉換成32位2進制補碼連同符號位,右移動指定的位數向右被移出的位被丟棄,左側用0填充
因為符號位變成了 0,所以結果總是正的
正數右移
正數時候 >> 和 >>> 結果是一樣的
5 >> 2 // 101 右移2位001 即:15 >>> 2 // 101 右移2位001 即:1負數右移-5>>>2//1073741822過程:-5 源碼: 10000000 00000000 00000000 00000101補碼:11111111 11111111 11111111 11111011右移兩位:00111111 11111111 11111111 11111110轉換成十進制即為:1073741822
問題:為什么這個要補滿32位,而之前的運算都沒有?因為之前的運算,正數補的都是0,負數雖然補1,但計算后要做補碼,補位的數最終不影響計算
而無符號右移,則會影響運算 。所以需要補全
練習
-23>>>245678765>>>31關于位運算的核心思路運算前要取補碼運算結果導致負數,再取一次補碼以上內容都是個人收集、以及多次嘗試整理的 。
因為網上看到的很多文章計算方式都不對,雖然舉的例子沒問題,但換機組數字就計算錯誤 。
- 正負數的加減乘除法則是什么 正負數的加減乘除法則
- 宇宙中在演化的最后階段有可能變為黑洞的天體是什么 宇宙中在演化的最后階段有可能變為黑洞的天體是
- 零是正數嗎 零是不是正數
- 非正數 最大的非正數是多少
- 除法法則 負數除法法則
- 正數 0是負數還是正數為什么
- 鎮魂武器開光有什么用_DNF鎮魂武器開光 鎮魂武器怎么變為釋魂?9?3
- 《DNF鎮魂武器開光 鎮魂武器怎么變為釋魂》 dnf怎么給傳說武器開光
- 法寶洗練_攻城略地如何將洗練密令變為開光點數
- 當瘦身變為生活方式時
