- 所有
JavaScript
數字存儲為根為10的64(8比特)浮點數。JavaScrip
t不是類型語言。與許多其他編程語言不同,JavaScript
不定義不同類型的數字,比如整數、短、長、浮點等等。- 整數精度(不使用小數點或指數計數法)最多為15位。小數精度的最大位數是17,但是浮點運算並不總是100% 准確。
- 位運算直接對二進制位進行計算,位運算直接處理每一個比特位,是非常底層的運算,好處是速度極快,缺點是很不直觀,許多場合不能夠使用。
- 位運算只對整數起作用,如果一個運算數不是整數,會自動轉為整數后再運行。
- 在
JavaScript
內部,數值都是以64位浮點數的形式儲存,但是做位運算的時候,是以32位帶符號的整數進行運算的,並且返回值也是一個32位帶符號的整數。
JS中常用的7個位運算符
1. 按位與(AND) &
&
以特定的方式組合操作二進制數中對應的位,如果對應的位都為1,那么結果就是1, 如果任意一個位是0 則結果就是0。
// 1的二進制表示為: 00000000 00000000 00000000 00000001 // 3的二進制表示為: 00000000 00000000 00000000 00000011 // ----------------------------- // 1的二進制表示為: 00000000 00000000 00000000 00000001 console.log(1 & 3) // 1 復制代碼
2. 按位或(OR) |
|
運算符跟 &
的區別在於如果對應的位中任一個操作數為1 那么結果就是1。
// 1的二進制表示為: 00000000 00000000 00000000 00000001 // 3的二進制表示為: 00000000 00000000 00000000 00000011 // ----------------------------- // 3的二進制表示為: 00000000 00000000 00000000 00000011 console.log(1 | 3) // 3 復制代碼
3. 按位異或(XOR) ^
^
如果對應兩個操作位有且僅有一個1時結果為1,其他都是0。
// 1的二進制表示為: 00000000 00000000 00000000 00000001 // 3的二進制表示為: 00000000 00000000 00000000 00000011 // ----------------------------- // 2的二進制表示為: 00000000 00000000 00000000 00000010 console.log(1 ^ 3) // 2 復制代碼
4. 按位非(NOT) ~
~
運算符是對位求反,1變0, 0變1,也就是求二進制的反碼。
// 1的二進制表示為: 00000000 00000000 00000000 00000001 // 3的二進制表示為: 00000000 00000000 00000000 00000011 // ----------------------------- // 1反碼二進制表示: 11111111 11111111 11111111 11111110 // 由於第一位(符號位)是1,所以這個數是一個負數。JavaScript 內部采用補碼形式表示負數,即需要將這個數減去1,再取一次反,然后加上負號,才能得到這個負數對應的10進制值。 // ----------------------------- // 1的反碼減1: 11111111 11111111 11111111 11111101 // 反碼取反: 00000000 00000000 00000000 00000010 // 表示為10進制加負號:-2 console.log(~ 1) // -2 復制代碼
- 簡單記憶:一個數與自身的取反值相加等於-1。
5. 左移(Left shift)<<
<<
運算符使指定值的二進制數所有位都左移指定次數,其移動規則:丟棄高位,低位補0即按二進制形式把所有的數字向左移動對應的位數,高位移出(舍棄),低位的空位補零。
// 1的二進制表示為: 00000000 00000000 00000000 00000001 // ----------------------------- // 2的二進制表示為: 00000000 00000000 00000000 00000010 console.log(1 << 1) // 2 復制代碼
6. 有符號右移>>
>>
該操作符會將指定操作數的二進制位向右移動指定的位數。向右被移出的位被丟棄,拷貝最左側的位以填充左側。由於新的最左側的位總是和以前相同,符號位沒有被改變。所以被稱作“符號傳播”。
// 1的二進制表示為: 00000000 00000000 00000000 00000001 // ----------------------------- // 0的二進制表示為: 00000000 00000000 00000000 00000000 console.log(1 >> 1) // 0 復制代碼
7. 無符號右移>>>
>>>
該操作符會將第一個操作數向右移動指定的位數。向右被移出的位被丟棄,左側用0填充。因為符號位變成了 0,所以結果總是非負的。(譯注:即便右移 0 個比特,結果也是非負的。)
對於非負數,有符號右移和無符號右移總是返回相同的結果。例如, 9 >>> 2
得到 2 和 9 >> 2
相同。
位運算符在js中的妙用
- 使用&運算符判斷一個數的奇偶
// 偶數 & 1 = 0 // 奇數 & 1 = 1 console.log(2 & 1) // 0 console.log(3 & 1) // 1 復制代碼
- 使用
~, >>, <<, >>>, |
來取整
console.log(~~ 6.83) // 6 console.log(6.83 >> 0) // 6 console.log(6.83 << 0) // 6 console.log(6.83 | 0) // 6 // >>>不可對負數取整 console.log(6.83 >>> 0) // 6 復制代碼
- 使用
^
來完成值交換
var a = 5 var b = 8 a ^= b b ^= a a ^= b console.log(a) // 8 console.log(b) // 5 復制代碼
- 使用
&, >>, |
來完成rgb值和16進制顏色值之間的轉換
/** * 16進制顏色值轉RGB * @param {String} hex 16進制顏色字符串 * @return {String} RGB顏色字符串 */ function hexToRGB(hex) { var hexx = hex.replace('#', '0x') var r = hexx >> 16 var g = hexx >> 8 & 0xff var b = hexx & 0xff return `rgb(${r}, ${g}, ${b})` } /** * RGB顏色轉16進制顏色 * @param {String} rgb RGB進制顏色字符串 * @return {String} 16進制顏色字符串 */ function RGBToHex(rgb) { var rgbArr = rgb.split(/[^\d]+/) var color = rgbArr[1]<<16 | rgbArr[2]<<8 | rgbArr[3] return '#'+ color.toString(16) } // ------------------------------------------------- hexToRGB('#ffffff') // 'rgb(255,255,255)' RGBToHex('rgb(255,255,255)') // '#ffffff' 復制代碼
參考
- https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators
- http://javascript.ruanyifeng.com/grammar/operator.html
- http://www.w3school.com.cn/js/js_obj_number.asp