位运算的妙用: 奇偶数, 色值换算,换值, 编码等
位运算的基础知识:
- 操作数是32位整数
- 自动转化为整数
- 在二进制下进行运算
一.按位与&
判断奇偶数:
- 奇数: num & 1 == 1
- 偶数: num & 1 == 0
基本知识:
- 用法:
操作数1 & 操作数2
- 规则:有 0 则为 0,双 1 则为 1
- 原理:先将
操作数1
和操作数2
转为二进制数,按照第2步进行计算
二.按位或|
按位或|取整
- num | 0
eg: 5.23 | 0 => 5.23 | 0的结果是5
按位或|
- 自身|自身=自身,可以比较数值相等(仅限于整数)
三.按位非~
按位非远算符(~),反转操作数的位. 表象是对数字为负, 然后减去1(-x-1)
eg: ~9 = -9 -1 = -10
按位非~: 判断数组中是否包含某个元素
- 不存在, indexOf返回-1
- ~-1 = -(-1)-1=1-1=0
- ~arr.indexOf(val) => 数组中不存在val这个值
按位非~取整
- ~~x
eg: ~~5.5677878 // 5
四.按位异或^
按位异或^ 归零律,恒等律,自反,集合律
- 归零律: a^a=0; 自己异或自己,位数上的值肯定相同
- 恒等律:a^0=a; 自己异或自己, 自己是啥结果是啥
- 自反: a^a^a=0^a = a; a三次^等于它自己
- 集合律: a^b^c == c^b^a, 与顺序无关
按位异或^ 值交换
- 变量值为数字,完成值的交换(不用增加临时变量)
示例:
let a = 10
let b = 20
a^=b //=> a = b^a => a^b
b^=a //=> b = a^b => (a^b) ^b => a ^ (b^b) => a ^ 0 => a => 结果是b=a
a^=b //=> a = b^a => b^b^b ^ (a^a) => b ^ 0 => b =>结果是: a = b
console.log('a:', a) // 20
console.log('b:', b) // 10
五.左移运算符:<<
<< 运算符执行左移位运算。
在移位运算过程中,符号位始终保持不变。
如果右侧空出位置,则自动填充为 0;
超出 32 位的值,则自动丢弃
console.log(5 << 2); // 20
基本知识:
- 用法:
操作数1 << 左移位数
- 规则:符号位不变,按位左移,右边补0
- 原理:先把
操作数1
转换为二进制数
六.右移运算符:>>
>> 运算符执行有符号右移位运算。
与左移运算操作相反,它把 32 位数字中的所有有效位整体右移,再使用符号位的值填充空位。
移动过程中超出的值将被丢弃。
console.log(1000 >> 8); // 3
基本知识:
- 用法:
操作数1 >> 右移位数
- 规则:符号位不变,按位右移,左边补0
- 原理:先把
操作数1
转换为二进制数
七.以下是JavaScript提供的二进制和十进制互转方法:
二进制转十进制方法: parseInt
parseInt(string, radix)
eg: console.log(parseInt(1010,2)); // 10
十进制转二进制: 字符串.toString(2)
同理: 十进制转16进制是: 字符串.toString(16)
eg:
const number = 10
console.log(number.toString(2)); // 1010
运用场景:
rgb和16进制颜色相互转换:
function colorRGBToHex(rgb) {
// split的参数可以是正则
const rgbArr= rgb.split(/[^\d]+/)
// ['', '数字1', '数字2', '数字3', '']
const color = rgbArr[1] << 16 | rgbArr[2] << 8 | rgbArr[3];
return `#${color.toString(16)}`
}
console.log(colorRGBToHex('rgb(204, 0, 255)'))
// 16进制转rgb格式
function colorHexToRGB(hex) {
// 转为6位的16进制, 0x??????
let newHex = hex.replace('#', '0x'),
r = newHex >> 16,
g = newHex >> 8 & 0xff,
b = newHex & 0xff
return `rgb(${r},${g},${b})`
}
console.log(colorHexToRGB('#CC00FF'))