关于javascript:位运算

位运算

js中的位运算只对整数起作用,因为位操作都有ToInt32这一步,从而舍弃小数局部

十六进制与二进制转换规则

十六进制 二进制
0 0000
1 0001
2 0010
3 0011
4 0100
5 0101
6 0110
7 0111
8 1000
9 1001
A 1010
B 1011
C 1100
D 1101
E 1110
F 1111

数的存储

计算机中数是以二进制补码进行存储的,负数的原码、反码、补码都是一样,正数的补码是原码的反码再加1,这样能够减法运算能够应用加法器实现,符号位也参加运算二进制的最高位为符号位0为正,1为负,以8位来算,最高位为符号位,其余7位示意数值),取反码与符号位无关。

int类型的数占用4字节(32位)。5转换成二进制是101,不满32位会在后面填充0。那么5在计算机中示意为:00000000 00000000 00000000 00000101

原码,反码与补码

原码:一个整数,依照绝对值大小转换成的二进制数;
反码:将二进制数按位取反【1变0,0变1】;
补码:反码加 1;

正数的二进制

如十进制: -5

        原码: 00000000 00000000 00000000 00000101
        反码:11111111 11111111 11111111 11111010
补码(反码加一):11111111 11111111 11111111 11111011

所以 -5 的二进制是 11111111 11111111 11111111 11111011,转换为十六进制:0xFFFFFFFB

二进制求整

如补码是:11111111 11111111 11111111 11110010

        补码: 11111111 11111111 11111111 11110010
反码(补码减一):11111111 11111111 11111111 11110001
按位取反,原码:00000000 00000000 00000000 00001110

原码00000000 00000000 00000000 00001110即14, 而后取反就是 -14。

<<左移

运算规定: 按二进制模式把所有的数字向左挪动对应的位数,高位移出(舍弃),低位的空位补零。
语法格局: 须要移位的数字 << 移位的次数。
数学意义: 如果是10进制向左挪动一位相当于乘10倍,移两位乘10的2次方倍,所以在数字没有溢出的前提下,对于负数和正数,二进制左移n位就相当于乘以2的n次方。

/** 3 << 2 **/
3转化为二进制: 00000011
    挪动补位:00001100
 转化为十进制:12

3 * 2 ^ 2 = 3 * 4 = 12

为什么没有无符号左移<<<?
因为左位移是填补左边空出的位,符号位不影响它的值。

>>带符号右移

运算规定: 按二进制模式把所有的数字向右挪动对应的位数,低位移出(舍弃),高位的空位补符号位,即负数补零,正数补1。【补的位数全副是符号位】
语法格局: 须要移位的数字 >> 移位的次数
数学意义: 右移一位相当于除2,右移n位相当于除以2的n次方。商若为小数,取整即可。

/** 11 >> 2 **/     
11转化为二进制: 0000 1011
     挪动补位:0000 0010
  转化为十进制:2

11 / 2^2 = 11 / 4 = 2

正数右移

例如: -100 >> 4【-100带符号右移4位】

        -100原码:00000000 00000000 00000000 01100100
        -100反码:11111111 11111111 11111111 10011011
        -100补码:11111111 11111111 11111111 10011100
右移4位,在高位补1:11111111 11111111 11111111 11111001

补码模式的移位实现后,后果不是移位后的后果,要依据补码写出原码才是最初的后果。

    减一:11111111 11111111 11111111 11111000
 按位取反:00000000 00000000 00000000 00000111
增加符号位:10000000 00000000 00000000 00000111
     后果:-7

>>>无符号右移

>>>运算符执行无符号右移位运算,它把无符号的 32 位整数所有数位整体右移。最左侧空位不再用符号位的值来填充,而是用 0 来填充。

// 对于无符号数或负数,无符号右移与有符号右移运算后果雷同。
console.log(1000 >> 8);  // 3
console.log(1000 >>> 8);  // 3

console.log(-1000 >> 8);  // -4
console.log(-1000 >>> 8);  // 16777212

~

运算规定: 操作数被转换为32位二进制示意(0和1)。超过32位的数字将抛弃其最高无效位。
语法格局: ~ 操作数。
数学意义: 任何数 x 的运算后果都是-(x + 1)~-5运算后果为`4;

/** ~ 5 **/
5转化为二进制: 00000000 00000000 00000000 00000101
    位数取反: 11111111 11111111 11111111 11111010 【补码】
       反码:11111111 11111111 11111111 11111001
       原码:00000000 00000000 00000000 00000110
  增加符号位:10000000 00000000 00000000 00000110
 转化为十进制: -6

const a = 5;
console.log(~a); // -6

&

运算规定: 第一个操作数的的第n位与第二个操作数的第n位比照,如果都是1,那么第n位的后果为1,否则为0;同真为真,一假为假

5转换为二进制:00000000 00000000 00000000 00000101
3转换为二进制:00000000 00000000 00000000 00000011
 5 & 3 后果:00000000 00000000 00000000 00000001

5 & 3 后果:00000000 00000000 00000000 00000001, 转化为二进制是1;

|

运算规定: 第一个操作数的的第n位与第二个操作数的第n位比照,只有有一个是1,那么第n位的后果为1,否则为0;一真为真,同假为假

5转换为二进制:00000000 00000000 00000000 00000101
3转换为二进制:00000000 00000000 00000000 00000011
  5 | 3 后果:00000000 00000000 00000000 00000111

5 | 3 后果:00000000 00000000 00000000 00000111, 转化为二进制是7;

^异或

运算规定: 第一个操作数的的第n位与第二个操作数的第n位比照,如果相同那么第n位后果的为1,否则为0;同为假,异为真

5转换为二进制:00000000 00000000 00000000 00000101
3转换为二进制:00000000 00000000 00000000 00000011
  5 ^ 3 后果:00000000 00000000 00000000 00000110

5 ^ 3 后果:00000000 00000000 00000000 00000110, 转化为二进制是6;

理论利用

  • 判断奇偶
a & 1 == 0; // 偶数
a & 1 == 1; // 奇数
  • 替换两个数的值

异或运算有如下个性:a ^ b ^ a = b; a ^ b ^ b = a

x ^= y;
y ^= x;
x ^= y;

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理