乐趣区

关于javascript:转位运算符在JS中的妙用

  • 所有 JavaScript 数字存储为根为 10 的 64(8 比特)浮点数。JavaScript 不是类型语言。与许多其余编程语言不同,JavaScript 不定义不同类型的数字,比方整数、短、长、浮点等等。
  • 整数精度(不应用小数点或指数计数法)最多为 15 位。小数精度的最大位数是 17,然而浮点运算并不总是 100% 精确。
  • 位运算间接对二进制位进行计算,位运算间接解决每一个比特位,是十分底层的运算,益处是速度极快,毛病是很不直观,许多场合不可能应用。
  • 位运算只对整数起作用,如果一个运算数不是整数,会主动转为整数后再运行。
  • 在 JavaScript 外部,数值都是以 64 位浮点数的模式贮存,然而做位运算的时候,是以 32 位带符号的整数进行运算的,并且返回值也是一个 32 位带符号的整数。

JS 中罕用的 7 个位运算符

按位与(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

按位或(OR) |

| 运算符跟 & 的区别在于如果对应的位中任一个操作数为 1 那么后果就是 1。

// 1 的二进制示意为: 00000000 00000000 00000000 00000001
// 3 的二进制示意为: 00000000 00000000 00000000 00000011
// -----------------------------
// 3 的二进制示意为: 00000000 00000000 00000000 00000011
console.log(1 | 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

按位非(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。

左移(Left shift)<<

<<运算符使指定值的二进制数所有位都左移指定次数,其挪动规定:抛弃高位,低位补 0 即按二进制模式把所有的数字向左挪动对应的位数,高位移出(舍弃),低位的空位补零。

// 1 的二进制示意为: 00000000 00000000 00000000 00000001
// -----------------------------
// 2 的二进制示意为: 00000000 00000000 00000000 00000010
console.log(1 << 1)     // 2

有符号右移>>

>>该操作符会将指定操作数的二进制位向右挪动指定的位数。向右被移出的位被抛弃,拷贝最左侧的位以填充左侧。因为新的最左侧的位总是和以前雷同,符号位没有被扭转。所以被称作“符号流传”。

// 1 的二进制示意为: 00000000 00000000 00000000 00000001
// -----------------------------
// 0 的二进制示意为: 00000000 00000000 00000000 00000000
console.log(1 >> 1)     // 0

无符号右移>>>

>>>该操作符会将第一个操作数向右挪动指定的位数。向右被移出的位被抛弃,左侧用 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…
http://javascript.ruanyifeng….
http://www.w3school.com.cn/js…

退出移动版