资讯专栏INFORMATION COLUMN

按位操作符

caiyongji / 1530人阅读

摘要:将任一数值与执行按位与操作,其结果都为。中应用判断奇偶性偶数奇数按位异或规则每一位都不同,结果才为将任一数值与进行异或操作,其结果为。

位运算在算法中很有用,速度可以比四则运算快很多。

To2orTo10

JS中十进制转二进制: (val).toString(2)
JS中二进制转十进制: parseInt(val, 2)

JS中规定安全整数的范围是-2^53~2^53,所以大于9007199254740991的数进制转换会存在精度问题

读取的十进制是根据原码来读取,而在内存中,数值都是以二进制补码形式保存的

十进制-5的二进制表示为:1000,0101(原码)
原码除符号位外,全部取反再+1:11111011(补码,内存存储形式)

~-5的结果:

正数的补码和原码一样

负数原码补码转换规则:
符号位不动,从低位往高位数,遇到第一个1之前,包括第一个1不作任何取反,之后,每位都取反。避免了原码转反码再转补码的繁琐。

{原码符号位不变} + {数值位按位取反后+1}

{原码符号位不变} + {数值位从右边数第一个1及其右边的0保持不变,左边安位取反}

// 7
00000111 // 原码
00000111 // 补码

// -6
10000110 // 原码
11111010 // 补码 // {原码符号位不变} + {数值位从右边数第一个1及其右边的0保持不变,左边安位取反}

// -6
10000110 // 原码
11111001 // 反码
11111010 // 补码 // {原码符号位不变} + {数值位按位取反后+1}

进行按位操作,都是针对补码去操作

十进制转二进制
1  1
2  10
3  11
4  100
5  101
6  110
7  111
8  1000
64
64 / 2 = 32 -> 0
32 / 2 = 16 -> 0
16 / 2 = 8 -> 1000
// 转为二进制为:100000

// 十进制 33 可以看成是 32 + 1 ,并且 33 应该是六位二进制的(因为 33 近似 32,而 32 是 2 的五次方,所以是六位),那么 十进制 33 就是 100001 ,只要是 2 的次方,那么就是 1否则都为 0
二进制转十进制

二进制100001同理,首位是2^5(1) ,末位是2^0(0),相加得出33(只要是 2 的次方,那么就是 1否则都为 0)

按位非(~) 取反

1(原码)转二进制: 00000001

按位取反: 11111110

将符号位之外的其它数字取反[符号位(即最高位)为1(表示负数)]: 10000001

末位加1取其补码: 10000010

转换会十进制: -2

00000001 // 原码
11111110 // 按位取反
10000001 // 除符号位取反
10000010 // +1

对任一数值 x 进行按位非操作的结果为 -(x + 1), 例如:2 -> -3

JS中的作用是配合indexOf()
indexOf找到一个给定元素的第一个索引,如果不存在,则返回-1, -1取反操作等于0,其它取反操作不等于0

if (~arr.indexOf(v))    if (arr.includes(v))
if (~str.indexOf(v))    if (str.indexOf(v) !== -1) 
按位或(|)

规则:其中一位为 1,结果就是 1

8 | 7
00001000
00000111
----------
00001111 // 15

任一数值 x 与 0 进行按位或操作,其结果都是 x:

6 | 0
00000110
00000000
---------
00000110 // 6

任一数值 x 与 -1 进行按位或操作,其结果都为 -1:

6 | -1
00000110
10000001
---------
10000111

将任一数值 x 与 0 进行按位或操作,其结果都是 x。将任一数值 x 与 -1 进行按位或操作,其结果都为 -1

JS中向下取整Math.floor, 返回小于或等于一个给定数字的最大整数

num | 0    or       Math.floor(num)
Math.floor(45.95);  // 45.95 | 0
// 45
Math.floor(45.05);  // 45.05 | 0
// 45 
Math.floor(4);  // 4 | 0
// 4 
Math.floor(-45.05);  // -45.05 | 0
// -46 
Math.floor(-45.95);  // -45.95 | 0
// -46
1 | 0 ;                       // 1

1.1 | 0 ;                     // 1

"asfdasfda" | 0 ;             // 0

0 | 0 ;                       // 0

(-1) | 0 ;                    // -1

(-1.5646) | 0 ;               // -1

[] | 0 ;                      // 0

({}) | 0 ;                    // 0

"123456" | 0 ;            // 123456

1.23E2 | 0;               // 123

1.23E12 | 0;              // 1639353344

-1.23E2 | 0;              // -123

-1.23E12 | 0;             // -1639353344
按位与(&)

规则:每一位都为 1,结果才为 1

8 & 7 // 0
00001000
00000111
00000000 // 0

将任一数值 x 与 0 执行按位与操作,其结果都为 0。将任一数值 x 与 -1 执行按位与操作,其结果都为 x。

JS中应用:
判断奇偶性

10 & 1 // 0 偶数
11 & 1 // 1 奇数
按位异或 (^)

规则:每一位都不同,结果才为 1

8 ^ 7 // 15
1000
0111
1111 // 15

8 ^ 8 // 0
1000
1000
0000 // 0

将任一数值 x 与 0 进行异或操作,其结果为 x。将任一数值 x 与 -1 进行异或操作,其结果为-x

不进位加法:
根据按位异或的特性就是不进位加法8 ^ 8 = 0 如果进位了,就是 16 了,所以只需要将两个数进行异或操作,然后进位。那么也就是说两个二进制都是1的位置,左边应该有一个进位1

JS中应用:
交换二个数值

let a = 3
let b = 4
a ^= b
b ^= a
a ^= b
有符号右移 (>>)

将第一个操作数向右移动指定的位数,向右被移出的位被丢弃,正数则在高位补零,负数则补1

9 >> 2

00001001 // 移动二位, 以0填充
00000010 // 2

-9 >> 2
10001001 // 原码
11110111 // 补码
11111101 // 补码右移
10000011 // 原码 // -3

公式:int v = a / (2 ^ b)

JS中的应用:
任何小数 把它>> 0可以取整

9.99 >> 0 // 9
9 >> 0 // 9
9.19 >> 0 // 9

除法运算:

9 >> 1 // 4
8 >> 1 // 4

二分算法中取中间值:

13 >> 1 // 6
12 >> 1 // 6
topic
两个数不使用四则运算得出和
a + b = (a ^ b) + ((a & b) << 1)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100460.html

相关文章

  • 【STM32】位操作按位与、按位或、按位异或、取反、左移、右移等基础 C 语言知识补充

    摘要:总结对于原二进制数来说,是不变,是反转。的位数对应原二进制数的位数,对各位进行屏蔽,全部置。左移左移与右移比较类似,是将目标二进制数字向左右移动相应的位数。语言中的逻辑运算符按位与,按位或,按位异或,取反,左右移位不完全手册立创开源 ...

    waruqi 评论0 收藏0
  • 浅谈JavaScript位作符

    摘要:有符号的右移操作符由两个大于符号表示这个操作符的含义就是将数值的位向右移指定的位数同时保留符号位的值正负号标记有符号的右移操作符与左移操作符刚好相反比如向右移动位就是同样的在移位的过程中也会出 位操作符的基本概念 因为ECMAscript中所有数值都是以IEEE-75464格式存储,所以才会诞生了位操作符的概念. 位操作符作用于最基本的层次上,因为数值按位存储,所以位操作符的作用也就是...

    fasss 评论0 收藏0
  • websocket 二进制数据传输基础准备工作

    摘要:例如,十进制数,用二进制表示则为。按位操作符操作数字的二进制形式,但是返回值依然是标准的数值。不同为真相同为假二进制按位异或运算从左到右按位非为真,为假对每一项进行非操作,遇真则假,遇假则真。 二进制与十六进制 二进制用 0 1 表示 2= 10十六进制 前缀0x 用0123456789ABCDEF表示 2= 0x2二进制与十六进制的转换十六进制的每位 等于二进制的四位 十六进制 0x...

    LeviDing 评论0 收藏0

发表评论

0条评论

caiyongji

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<