JS位运算与加减法

位运算

位与(&)

真真为真,其余为假

var a1 = 7;
var a2 = 5;
var b1 = a1.toString(2);      //111
var b2 = a2.toString(2);      //101
console.log(b1,b2);
var c = a1 & a2;   //5
console.log(c);
console.log(c.toString(2));   //101
运用:判断奇偶

奇数的二进制末位为1,偶数为0,跟1的位与运算后,分别为1和0,因此可以用位与运算来判断奇偶数。

var n = 3;
if(n & 1) {
    console.log('n为奇数');
} else {
    console.log('n为偶数');
}
//n为奇数

位或(|)

假假为假,其余为真

var a1 = 7;
var a2 = 5;
var b1 = a1.toString(2);      //111
var b2 = a2.toString(2);      //101
console.log(b1,b2);
var c = a1 | a2;   //7
console.log(c);
console.log(c.toString(2));   //111
运用:取整

整数与0的位或运算,都是本身。浮点数不支持位运算,过程中会自动转化成整数,利用这一点,可以将浮点数与0进行位或运算即可达到取整目的。

console.log(11.23 | 0);   //11

位或(~)

位运算 NOT 是三步的处理过程:

  1. 把运算数转换成 32 位数字
  2. 把二进制数转换成它的二进制反码
  3. 把二进制数转换成浮点数
var a = 1;
var b = ~a;
console.log(b);              //-2
console.log(b.toString(2));  //-10,即1000 0010
//步骤
//1.将1转二进制              0000 0001
//2.按位取反                 1111 1110
//3.发现符号位(即最高位)
//为1(表示负数),将除符号位
//之外的其他数字取反          1000 0001
//4.末位加1得                1000 0010
//5.转换成十进制              -2

参考1
参考2

运用:快速计算

~A = ~(A + 1)

运用:取整

双按位非可以对数进行取整,一个按位非操作符~首先将输入input截取为32位,然后将其转换为-(input+1)。因此双按位非操作符将输入转换为-(-(input + 1)+1),使其成为一个趋向于0取整的好工具。

console.log(~~(9.6));       //9
console.log(~~(9.1));       //9
console.log(~~(-10.3));     //-10
console.log(~~(-10.9));     //-10

参考链接:取整及注意点

异或(^)

相同为假,不同为真

var a1 = 7;
var a2 = 5;
var b1 = a1.toString(2);      //111
var b2 = a2.toString(2);      //101
console.log(b1,b2);
var c = a1 ^ a2;   //2
console.log(c);
console.log(c.toString(2));   //010
运用:交换
var a = 7;
var b = 5;
a ^= b;
b ^= a;
a ^= b;
console.log(a); // 5
console.log(b); // 7

异或交换知识及注意点

有符号左移(<<)

首位符号为不动,把32位二进制数字整体往左边移动指定位数,左边超出部分被舍去,右边补0。

console.log(9 << 3);            //72
//1. 9转化为二进制               
//0000 0000 0000 0000 0000 0000 0000 1001
//2. 符号为不动,其余往左移动3位  
//0000 0000 0000 0000 0000 0000 0100 1000
//3.转化为十进制                 72
运用:计算

m << n,把m左移n位,实际上是扩大了2的n次方倍
即结果c = num * (2^n),即:9*Math.pow(2,3) = 72

有符号右移(>>)

首位符号为不动,把32位二进制数字整体往右边移动指定位数,右边超出部分被舍去,左边补0。

console.log(17 >> 3);            //2
//1. 9转化为二进制               
//0000 0000 0000 0000 0000 0000 0001 0001
//2. 符号为不动,其余往左移动3位  
//0000 0000 0000 0000 0000 0000 0000 0010
//3.转化为十进制                 2
运用:计算

m >> n,把m右移n位,实际上是缩小了2的n次方倍
即结果c = num /(2^n),即:17/Math.pow(2,3) ,结果取整得2

无符号右移(>>>)

符号为也跟着一起移动

console.log(-14>>>2);            //1073741820
//1. 转化为二进制               11111111 11111111 11111111 11110010
//2. 往左移动3位  00111111 11111111 11111111 11111100
//3.转化为十进制                 1073741820

实例
负数求补码

总结

参考资料

加减法

原理参考这里不再赘述

加法

function add(a,b){
    if(a == 0 || b == 0){
      return a||b
    }
    var num;
    while(b != 0){
      num = a ^ b;      //异或:不看进位的结果
      b = (a & b) << 1; //与运算且向左移一位:只看进位的结果 
      a = num;           
    }
    return a;
}

var t = add(3,5);
console.log(t);   //8

减法

function sub(a,b){
    if(a == 0 || b == 0){
      return a || -b
    }
    b = ~ b;
    var num;
    while(b != 0){
      num = a ^ b;
      b = (a & b) << 1;
      a = num;
    }
    return a + 1;
}

var a1 = sub(7,7);
var a2 = sub(7,9);
var a3 = sub(10,5);
console.log(a1,a2,a3);  //0 -2 5

你可能感兴趣的:(javascript,前端,javascript,前端,开发语言)