当前位置:网站首页>少见的按位操作符
少见的按位操作符
2022-07-27 14:39:00 【前行的枫】
按位操作符(Bitwise operators) 将其操作数(operands)当作32位的比特序列(由0和1组成),而不是十进制、十六进制或八进制数值。例如,十进制数9,用二进制表示则为1001。按位操作符操作数字的二进制形式,但是返回值依然是标准的JavaScript数值(来自MDN)。
也就是将操作数转成一串32位的二进制。按位操作符进行运算前先要转成32位的二进制(超过32位的会被丢弃)。如何丢弃的?
丢弃前: 11100110111110100000000000000110000000000001
丢弃后: 10100000000000000110000000000001
二进制又是什么?二进制是一串比特序列(由0和1组成)
二进制怎么转?我们的操作数一般都是十进制的,也就是十进制转二进制。
二进制转十进制:
00000000 00000000 00000000 00000101
=>
结果:1*2^0 + 0*2^1 + 1*2^1 = 5 (^表示次方)
十进制转二进制:
233
=>
对233及其结果依次除以2,将余数结果从右至左排序。
233 / 2 => 1
116 / 2 => 0
58 / 2 => 0
29 / 2 => 1
14 / 2 => 0
7 / 2 => 1
3 / 2 => 1
1 / 2 => 1
结果:00000000 00000000 00000000 11101001
**按位操作符种类**
| 运算符 | 用法 | 描述 |
|---|---|---|
| 按位与 | a & b | 对于每一个比特位,只有两个操作数相应的比特位都是1时,结果才为1,否则为0。 |
| 按位或 | a I b | 对于每一个比特位,当两个操作数相应的比特位至少有一个1时,结果为1,否则为0。 |
| 按位异或 | a ^ b | 对于每一个比特位,当两个操作数相应的比特位有且只有一个1时,结果为1,否则为0。 |
| 按位非 | ~ a | 反转操作数的比特位,即0变成1,1变成0。 |
| 左移 | a << b | 将 a 的二进制形式向左移 b (< 32) 比特位,右边用0填充。 |
| 有符号右移 | a >> b | 将 a 的二进制表示向右移 b (< 32) 位,丢弃被移出的位。 |
| 无符号右移 | a >>> b | 将 a 的二进制表示向右移 b (< 32) 位,丢弃被移出的位,并使用 0 在左侧填充。 |
按位操作符可以这个理解,就是按照比特位进行相应的操作
& (按位与)
对每对比特位执行与操作。只有这对比特位都是 1 时,与操作后才是 1,否则为0。
9 = 00000000000000000000000000001001
14 = 00000000000000000000000000001110
14 & 9 = 00000000000000000000000000001000 = 8
| (按位或)
对每一对比特位执行或操作。如果这对比特位至少有一个为1 时,或操作后才是 1,否则为0。
9 = 00000000000000000000000000001001
14 = 00000000000000000000000000001110
14 | 9 = 00000000000000000000000000001111 = 15
^ (按位异或)
对每一对比特位执行异或操作。如果这对比特位不同时,异或操作后才是 1,否则为0。
9 = 00000000000000000000000000001001
14 ^ 9 = 00000000000000000000000000000111 = 7
~(按位非)
对每个特位执行非操作。 就是对比特位反转(即反码)。
9 = 00000000000000000000000000001001
~ 9 = 11111111111111111111111111110110 = -10
等等为什么是 -10?
由于第一位(符号位,即最左边的那位)是1,所以这个数是一个负数,为0则为正数。
JavaScript 内部采用补码形式表示负数,
即需要将这个数减去1,再取一次反,然后加上负号,才能得到这个负数对应的10进制值。
减1之后:11111111111111111111111111110101
再取反:00000000000000000000000000001010 = 10 然后加上负号,就是-10了
<<(左移)
该操作符会将第一个操作数向左移动指定的位数。向左被移出的位被丢弃,右侧用 0 补充。
9 = 00000000000000000000000000001001
9 << 2 = 00000000000000000000000000100100 = 36
>>(有符号右移)
该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,拷贝最左侧的位以填充左侧。由于新的最左侧的位总是和以前相同,符号位没有被改变。所以被称作“符号传播”。
9 = 00000000000000000000000000001001
9 >> 2 = 00000000000000000000000000000010 = 2
>>> (无符号右移)
该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,左侧用0填充。因为符号位变成了 0,所以结果总是非负的。(译注:即便右移 0 个比特,结果也是非负的。)
9 = 00000000000000000000000000001001
9 >>> 2 = 00000000000000000000000000000010 = 2
按位操作符的用处
例子来源掘金大佬:https://juejin.im/post/5a98ea2f6fb9a028bb186f34#comment
1.使用&运算符判断一个数的奇偶
// 偶数 & 1 = 0
// 奇数 & 1 = 1
console.log(2 & 1) // 0
console.log(3 & 1) // 1
2.使用~, >>, <<, >>>, |来取整
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
3.使用^来完成值交换
var a = 5
var b = 8
a ^= b
b ^= a
a ^= b
console.log(a) // 8
console.log(b) // 5
4.使用&, >>, |来完成rgb值和16进制颜色值之间的转换
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})`
}
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'
边栏推荐
- Clickhouse 20.x distributed table testing and chproxy deployment (II)
- The shell script reads the redis command in the text and inserts redis in batches
- /Dev/loop1 takes up 100% of the problem
- IP protocol of network layer
- First acquaintance with MySQL database
- 数组名是首元素地址吗?
- Talk about ThreadLocal
- Pycharm导入已有的本地安装包
- Ncnn reasoning framework installation; Onnx to ncnn
- Go language slow start - package
猜你喜欢

Static关键字的三种用法

Division of entity classes (VO, do, dto)

C language: string function and memory function

C语言:函数栈帧

Is low code the future of development? On low code platform

折半查找

Binder初始化过程

多线程带来的的风险——线程安全
![[sword finger offer] interview question 42: the maximum sum of continuous subarrays -- with 0x80000000 and int_ MIN](/img/01/bbf81cccb47b6351d7265ee4a77c55.png)
[sword finger offer] interview question 42: the maximum sum of continuous subarrays -- with 0x80000000 and int_ MIN

C language: Sanzi game
随机推荐
Voice live broadcast system -- a necessary means to improve the security of cloud storage
MySQL表数据的增删查改
Insert sort directly
DRF学习笔记(五):视图集ViewSet
QT (VI) value and string conversion
传美国政府将向部分美企发放对华为销售许可证!
SQL multi table query
Understand │ what is cross domain? How to solve cross domain problems?
Go language slow start -- go operator
go语言慢速入门——基本内置类型
js操作dom节点
判断数据的精确类型
Stock account opening commission discount, stock trading account opening which securities company is good, is online account opening safe
Six capabilities of test and development
IP protocol of network layer
Catalog component design and custom extended catalog implementation in spark3
台积电的反击:指控格芯侵犯25项专利,并要求禁售!
[tensorboard] oserror: [errno 22] invalid argument processing
突发!海康/大华/商汤/旷视/依图/科大讯飞等28家中国实体被美列入黑名单
[sword finger offer] interview question 50: the first character that appears only once - hash table lookup