js中位运算的运用实例分析


Posted in Javascript onDecember 11, 2018

我们可能很少在编程中用位运算,如果没深入学习,可能也很难理解。平时的数值运算,其实是要先转换成二进制再进行运算的,而位运算就是直接进行二进制运算,所以位运算的执行效率肯定是更高的。下面通过一些实例来加深对位运算的理解。

按位与(&)

&&运算符我们都知道,只有两个都为真,结果才为真。&道理是一样的,只有两个数的值为1时,才返回1。例如1和3的按位与操作:

    0001
&  0011
  ---------
    0001

只有对应的数为1时,结果才为1,其他都为0。
判断一个数是奇数还是偶数,我们会用求余数来判断:

function assert(n) {
  if (n % 2 === 1) {
 console.log("n是奇数");
 } else {
 console.log("n是偶数");
 }
}

assert(3); // "n是奇数"

我们也可以用一个数和1进行按位&操作来判断,而且速度更快:

function assert(n) {
if (n & 1) {
 console.log("n是奇数");
} else {
 console.log("n是偶数");
}
}

assert(3); // "n是奇数"

下面是位运算过程:

1 = 0001
3 = 0011
--------
   & = 0001

奇数的二进制码的最后一位数肯定是1,而1只有最后一位为1,按位&操作之后,结果肯定只有最后一位数为1。而偶数的二进制表示的最后一位数是0,和1进行按位&操作,结果所有位数都为0。

按位或(|)

|与||操作符的道理也是一样的,只要两个数中有一个数为1,结果就为1,其他则为0。

  0001
| 0011
 ---------
  0011

对浮点数向下求整,我们会用下面的方法:

var num = Math.floor(1.1); // 1

我们也可以用位运算来求整:

var num = 1.1 | 0; // 1

其实浮点数是不支持位运算的,所以会先把1.1转成整数1再进行位运算,就好像是对浮点数向下求整。所以1|0的结果就是1。

按位非(~)

按位非就是求二进制的反码:

var num = 1; // 二进制 00000000000000000000000000000001
var num1 = ~num; // 二进制 11111111111111111111111111111110

我们知道,js中的数字默认是有符号的。有符号的32位二进制的最高位也就是第一位数字代表着正负,1代表负数,0代表整数。那到底11111111111111111111111111111110等于多少呢?最高位为1代表负数,负数的二进制转化为十进制:符号位不变,其他位取反加1。取反之后为10000000000000000000000000000001,加1之后为10000000000000000000000000000010,十进制为-2。

按位异或(^)

按位异或是两个数中只有一个1时返回1,其他情况返回0。

   0001
^ 0011
 ---------
  0010

数字与数字本身按位异或操作得到的是0,因为每两个对应的数字都相同,所以最后返回的都是0。

我们经常会需要调换两个数字的值:

var num1 = 1, num2 = 2, temp;
temp = num1;
num1 = num2; // 2
num2 = temp; // 1

如果装逼一点的话,可以这样:

var num1 = 1, num2 = 2;
num1 = [num2, num2 = num1][0];
console.log(num1); // 2
console.log(num2); // 1

如果想再装的稳一点的话,可以这样:

var num1 = 1, num2 = 2;
num1 ^= num2; // num1 = num1 ^ num2 = 1 ^ 2 = 3
num2 ^= num1; // num2 = num2 ^ (num1 ^ num2) = 2 ^ (1 ^ 2) = 1
num1 ^= num2; // num1 = num1 ^ num2 = 3 ^ 1 = 2
console.log(num1); // 2
console.log(num2); // 1

有符号左移(<<)

有符号左移会将32位二进制数的所有位向左移动指定位数。如:

var num = 2; // 二进制10
num = num << 5; // 二进制1000000,十进制64

如果要求2的n次方,可以这样:

function power(n) {
 return 1 << n;
}

power(5); // 32

1的二进制是01,左移5位就是0100000,十进制就是2的5次方32。

有符号右移(>>)

有符号右移会将32位二进制数的所有位向右移动指定位数。如:

var num = 64; // 二进制1000000
num = num >> 5; // 二进制10,十进制2

求一个数的二分之一:

var num = 64 >> 1; // 32

有符号左移与右移不会影响符号位。

无符号右移(>>>)

正数的无符号右移与有符号右移结果是一样的。负数的无符号右移会把符号位也一起移动,而且无符号右移会把负数的二进制码当成正数的二进制码:

var num = -64; // 11111111111111111111111111000000
num = num >>> 5; // 134217726

所以,我们可以利用无符号右移来判断一个数的正负:

function isPos(n) {
return (n === (n >>> 0)) ? true : false; 
}

isPos(-1); // false
isPos(1); // true

-1>>>0虽然没有向右移动位数,但-1的二进制码已经变成了正数的二进制码:

11111111111111111111111111111111

所以-1>>>0的值为4294967295。

总结

以上的例子在平常可能会比较容易用到或看到,也是属于比较容易理解的。一些比较复杂的、难理解的,我觉得应该尽量少用,因为会给阅读者带来困难,也会给自己带来麻烦。

Javascript 相关文章推荐
3种js实现string的substring方法
Nov 09 Javascript
JavaScript实现输入框(密码框)出现提示语
Jan 12 Javascript
百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换
Feb 19 Javascript
javascript实现PC网页里的拖拽效果
Mar 14 Javascript
一起学写js Calender日历控件
Apr 14 Javascript
JavaScript笛卡尔积超简单实现算法示例
Jul 30 Javascript
jQuery滑动效果实现方法分析
Sep 05 jQuery
Vue.js如何使用Socket.IO的示例代码
Sep 05 Javascript
微信小程序实现点击按钮后修改颜色
Dec 05 Javascript
详解vue中在循环中使用@mouseenter 和 @mouseleave事件闪烁问题解决方法
Apr 07 Javascript
js实现弹窗效果
Aug 09 Javascript
解决Vue项目中tff报错的问题
Oct 21 Javascript
js中的数组对象排序分析
Dec 11 #Javascript
详解Vue源码之数据的代理访问
Dec 11 #Javascript
浅谈Vue 性能优化之深挖数组
Dec 11 #Javascript
vue 内置过滤器的使用总结(附加自定义过滤器)
Dec 11 #Javascript
Vue入门之数量加减运算操作示例
Dec 11 #Javascript
简单的React SSR服务器渲染实现
Dec 11 #Javascript
Vuex 单状态库与多模块状态库详解
Dec 11 #Javascript
You might like
destoon调用自定义模板及样式的公告栏
2014/06/21 PHP
php+ajax实时输入自动搜索匹配的方法
2014/12/26 PHP
php读取出一个文件夹及其子文件夹下所有文件的方法示例
2017/06/15 PHP
PHP实现求解最长公共子串问题的方法
2017/11/17 PHP
php中html_entity_decode实现HTML实体转义
2018/06/13 PHP
Laravel框架自定义验证过程实例分析
2019/02/01 PHP
PHPStorm 2020.1 调试 Nodejs的多种方法详解
2020/09/17 NodeJs
Jquery ui css framework
2010/06/28 Javascript
javascript获取网页中指定节点的父节点、子节点的方法小结
2013/04/24 Javascript
extjs中form与grid交互数据(record)的方法
2013/08/29 Javascript
js面向对象编程之如何实现方法重载
2014/07/02 Javascript
关于angularJs指令的Scope(作用域)介绍
2016/10/25 Javascript
js实现一个简单的MVVM框架示例
2018/01/15 Javascript
在create-react-app中使用sass的方法示例
2018/10/01 Javascript
使用 Vue cli 3.0 构建自定义组件库的方法
2019/04/30 Javascript
Vue3.x源码调试的实现方法
2019/10/13 Javascript
node.js使用fs读取文件出错的解决方案
2019/10/23 Javascript
vue+Element-ui实现登录注册表单
2020/11/17 Javascript
Python的Django框架中的表单处理示例
2015/07/17 Python
python利用标准库如何获取本地IP示例详解
2017/11/01 Python
Python 25行代码实现的RSA算法详解
2018/04/10 Python
python实现梯度下降算法
2020/03/24 Python
Python单元测试与测试用例简析
2019/11/09 Python
python通过nmap扫描在线设备并尝试AAA登录(实例代码)
2019/12/30 Python
一款利用纯css3实现的win8加载动画的实例分析
2014/12/11 HTML / CSS
Html5 Canvas 实现一个“刮刮乐”游戏
2019/09/05 HTML / CSS
美国沃尔玛网上超市:Walmart
2020/08/14 全球购物
金蝶的一道SQL笔试题
2012/12/18 面试题
简短的公司员工自我评价分享
2013/11/13 职场文书
美国探亲签证邀请信
2014/02/05 职场文书
大学四年个人的自我评价
2014/02/26 职场文书
音乐兴趣小组活动总结
2014/07/07 职场文书
领导欢迎词范文
2015/01/26 职场文书
幼儿园亲子活动通知
2015/04/24 职场文书
2016年国庆节宣传标语
2015/11/25 职场文书
【TED出品】天梯非主流开心游1700 划水骑士
2022/03/31 魔兽争霸