js三进制计算机,js 笔记 - 二进制位运算符
概述
二進制位運算符用于直接對二進制位進行計算,一共有7個。二進制或運算符(or):符號為|,表示若兩個二進制位都為0,則結果為0,否則為1。
二進制與運算符(and):符號為&,表示若兩個二進制位都為1,則結果為1,否則為0。
二進制否運算符(not):符號為~,表示對一個二進制位取反。
異或運算符(xor):符號為^,表示若兩個二進制位不相同,則結果為1,否則為0。
左移運算符(left shift):符號為<
右移運算符(right shift):符號為>>,詳見下文解釋。
頭部補零的右移運算符(zero filled right shift):符號為>>>,詳見下文解釋。
這些位運算符直接處理每一個比特位(bit),所以是非常底層的運算,好處是速度極快,缺點是很不直觀,許多場合不能使用它們,否則會使代碼難以理解和查錯。
有一點需要特別注意,位運算符只對整數起作用,如果一個運算子不是整數,會自動轉為整數后再執行。另外,雖然在 JavaScript 內部,數值都是以64位浮點數的形式儲存,但是做位運算的時候,是以32位帶符號的整數進行運算的,并且返回值也是一個32位帶符號的整數。i?=?i?|?0;復制代碼
上面這行代碼的意思,就是將i(不管是整數或小數)轉為32位整數。
利用這個特性,可以寫出一個函數,將任意數值轉為32位整數。function?toInt32(x)?{
return?x?|?0;
}復制代碼
上面這個函數將任意值與0進行一次或運算,這個位運算會自動將一個值轉為32位整數。下面是這個函數的用法。toInt32(1.001)?//?1
toInt32(1.999)?//?1
toInt32(1)?//?1
toInt32(-1)?//?-1
toInt32(Math.pow(2,?32)?+?1)?//?1
toInt32(Math.pow(2,?32)?-?1)?//?-1復制代碼
上面代碼中,toInt32可以將小數轉為整數。對于一般的整數,返回值不會有任何變化。對于大于或等于2的32次方的整數,大于32位的數位都會被舍去。
二進制或運算符
二進制或運算符(|)逐位比較兩個運算子,兩個二進制位之中只要有一個為1,就返回1,否則返回0。0?|?3?//?3復制代碼
上面代碼中,0和3的二進制形式分別是00和11,所以進行二進制或運算會得到11(即3)。
位運算只對整數有效,遇到小數時,會將小數部分舍去,只保留整數部分。所以,將一個小數與0進行二進制或運算,等同于對該數去除小數部分,即取整數位。2.9?|?0?//?2
-2.9?|?0?//?-2復制代碼
需要注意的是,這種取整方法不適用超過32位整數最大值2147483647的數。2147483649.4?|?0;
//?-2147483647復制代碼
二進制與運算符
二進制與運算符(&)的規則是逐位比較兩個運算子,兩個二進制位之中只要有一個位為0,就返回0,否則返回1。0?&?3?//?0復制代碼
上面代碼中,0(二進制00)和3(二進制11)進行二進制與運算會得到00(即0)。
二進制否運算符
二進制否運算符(~)將每個二進制位都變為相反值(0變為1,1變為0)。它的返回結果有時比較難理解,因為涉及到計算機內部的數值表示機制。~?3?//?-4復制代碼
上面表達式對3進行二進制否運算,得到-4。之所以會有這樣的結果,是因為位運算時,JavaScript 內部將所有的運算子都轉為32位的二進制整數再進行運算。
3的32位整數形式是00000000000000000000000000000011,二進制否運算以后得到11111111111111111111111111111100。由于第一位(符號位)是1,所以這個數是一個負數。JavaScript 內部采用補碼形式表示負數,即需要將這個數減去1,再取一次反,然后加上負號,才能得到這個負數對應的10進制值。這個數減去1等于11111111111111111111111111111011,再取一次反得到00000000000000000000000000000100,再加上負號就是-4??紤]到這樣的過程比較麻煩,可以簡單記憶成,一個數與自身的取反值相加,等于-1。~?-3?//?2復制代碼
上面表達式可以這樣算,-3的取反值等于-1減去-3,結果為2。
對一個整數連續兩次二進制否運算,得到它自身。~~3?//?3復制代碼
所有的位運算都只對整數有效。二進制否運算遇到小數時,也會將小數部分舍去,只保留整數部分。所以,對一個小數連續進行兩次二進制否運算,能達到取整效果。~~2.9?//?2
~~47.11?//?47
~~1.9999?//?1
~~3?//?3復制代碼
使用二進制否運算取整,是所有取整方法中最快的一種。
對字符串進行二進制否運算,JavaScript 引擎會先調用Number函數,將字符串轉為數值。//?相當于~Number('011')
~'011'??//?-12
//?相當于~Number('42?cats')
~'42?cats'?//?-1
//?相當于~Number('0xcafebabe')
~'0xcafebabe'?//?889275713
//?相當于~Number('deadbeef')
~'deadbeef'?//?-1復制代碼
Number函數將字符串轉為數值的規則,參見《數據的類型轉換》一章。
對于其他類型的值,二進制否運算也是先用Number轉為數值,然后再進行處理。//?相當于?~Number([])
~[]?//?-1
//?相當于?~Number(NaN)
~NaN?//?-1
//?相當于?~Number(null)
~null?//?-1復制代碼
異或運算符
異或運算(^)在兩個二進制位不同時返回1,相同時返回0。0?^?3?//?3復制代碼
上面表達式中,0(二進制00)與3(二進制11)進行異或運算,它們每一個二進制位都不同,所以得到11(即3)。
“異或運算”有一個特殊運用,連續對兩個數a和b進行三次異或運算,a^=b; b^=a; a^=b;,可以互換它們的值。這意味著,使用“異或運算”可以在不引入臨時變量的前提下,互換兩個變量的值。var?a?=?10;
var?b?=?99;
a?^=?b,?b?^=?a,?a?^=?b;
a?//?99
b?//?10復制代碼
這是互換兩個變量的值的最快方法。
異或運算也可以用來取整。12.9?^?0?//?12復制代碼
左移運算符
左移運算符(<
//?左移一位為1000(即十進制的8)
//?相當于乘以2的1次方
4?<
//?8
-4?<
//?-8復制代碼
上面代碼中,-4左移一位得到-8,是因為-4的二進制形式是11111111111111111111111111111100,左移一位后得到11111111111111111111111111111000,該數轉為十進制(減去1后取反,再加上負號)即為-8。
如果左移0位,就相當于將該數值轉為32位整數,等同于取整,對于正數和負數都有效。13.5?<
//?13
-13.5?<
//?-13復制代碼
左移運算符用于二進制數值非常方便。var?color?=?{r:?186,?g:?218,?b:?85};
//?RGB?to?HEX
//?(1?<
var?rgb2hex?=?function(r,?g,?b)?{
return?'#'?+?((1?<
.toString(16)?//?先轉成十六進制,然后返回字符串
.substr(1);???//?去除字符串的最高位,返回后面六個字符串
}
rgb2hex(color.r,?color.g,?color.b)
//?"#bada55"復制代碼
上面代碼使用左移運算符,將顏色的 RGB 值轉為 HEX 值。
右移運算符
右移運算符(>>)表示將一個數的二進制值向右移動指定的位數。如果是正數,頭部全部補0;如果是負數,頭部全部補1。右移運算符基本上相當于除以2的指定次方(最高位即符號位參與移動)。4?>>?1
//?2
/*
//?因為4的二進制形式為?00000000000000000000000000000100,
//?右移一位得到?00000000000000000000000000000010,
//?即為十進制的2
*/
-4?>>?1
//?-2
/*
//?因為-4的二進制形式為?11111111111111111111111111111100,
//?右移一位,頭部補1,得到?11111111111111111111111111111110,
//?即為十進制的-2
*/復制代碼
右移運算可以模擬 2 的整除運算。5?>>?1
//?2
//?相當于?5?/?2?=?2
21?>>?2
//?5
//?相當于?21?/?4?=?5
21?>>?3
//?2
//?相當于?21?/?8?=?2
21?>>?4
//?1
//?相當于?21?/?16?=?1復制代碼
頭部補零的右移運算符
頭部補零的右移運算符(>>>)與右移運算符(>>)只有一個差別,就是一個數的二進制形式向右移動時,頭部一律補零,而不考慮符號位。所以,該運算總是得到正值。對于正數,該運算的結果與右移運算符(>>)完全一致,區別主要在于負數。4?>>>?1
//?2
-4?>>>?1
//?2147483646
/*
//?因為-4的二進制形式為11111111111111111111111111111100,
//?帶符號位的右移一位,得到01111111111111111111111111111110,
//?即為十進制的2147483646。
*/復制代碼
這個運算實際上將一個值轉為32位無符號整數。
查看一個負整數在計算機內部的儲存形式,最快的方法就是使用這個運算符。-1?>>>?0?//?4294967295復制代碼
上面代碼表示,-1作為32位整數時,內部的儲存形式使用無符號整數格式解讀,值為 4294967295(即(2^32)-1,等于11111111111111111111111111111111)。
開關作用
位運算符可以用作設置對象屬性的開關。
假定某個對象有四個開關,每個開關都是一個變量。那么,可以設置一個四位的二進制數,它的每個位對應一個開關。var?FLAG_A?=?1;?//?0001
var?FLAG_B?=?2;?//?0010
var?FLAG_C?=?4;?//?0100
var?FLAG_D?=?8;?//?1000復制代碼
上面代碼設置 A、B、C、D 四個開關,每個開關分別占有一個二進制位。
然后,就可以用二進制與運算,檢查當前設置是否打開了指定開關。var?flags?=?5;?//?二進制的0101
if?(flags?&?FLAG_C)?{
//?...
}
//?0101?&?0100?=>?0100?=>?true復制代碼
上面代碼檢驗是否打開了開關C。如果打開,會返回true,否則返回false。
現在假設需要打開A、B、D三個開關,我們可以構造一個掩碼變量。var?mask?=?FLAG_A?|?FLAG_B?|?FLAG_D;
//?0001?|?0010?|?1000?=>?1011復制代碼
上面代碼對A、B、D三個變量進行二進制或運算,得到掩碼值為二進制的1011。
有了掩碼,二進制或運算可以確保打開指定的開關。flags?=?flags?|?mask;復制代碼
上面代碼中,計算后得到的flags變量,代表三個開關的二進制位都打開了。
二進制與運算可以將當前設置中凡是與開關設置不一樣的項,全部關閉。flags?=?flags?&?mask;復制代碼
異或運算可以切換(toggle)當前設置,即第一次執行可以得到當前設置的相反值,再執行一次又得到原來的值。flags?=?flags?^?mask;復制代碼
二進制否運算可以翻轉當前設置,即原設置為0,運算后變為1;原設置為1,運算后變為0。flags?=?~flags;復制代碼
總結
以上是生活随笔為你收集整理的js三进制计算机,js 笔记 - 二进制位运算符的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 芬兰计算机研究生申请表,芬兰的研究生申请
- 下一篇: 远程恢复服务器,Hyper-V主机启用“