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 相关文章推荐
LazyForm jQuery plugin 定制您的CheckBox Radio和Select
Oct 24 Javascript
JQUERY对单选框(radio)操作的小例子
Apr 25 Javascript
js实现touch移动触屏滑动事件
Apr 17 Javascript
JS如何设置cookie有效期为当天24点并弹出欢迎登陆界面
Aug 04 Javascript
Bootstrap3 图片(响应式图片&amp;图片形状)
Jan 04 Javascript
JavaScript基础进阶之数组方法总结(推荐)
Sep 04 Javascript
jQuery实现遍历XML节点和属性的方法示例
Apr 29 jQuery
vuex与组件联合使用的方法
May 10 Javascript
通过实例讲解JS如何防抖动
Jun 15 Javascript
在weex中愉快的使用scss的方法步骤
Jan 02 Javascript
详解JavaScript之ES5的继承
Jul 08 Javascript
jenkins自动构建发布vue项目的方法步骤
Jan 04 Vue.js
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
叶罗丽:为什么大家对颜冰这对CP非常关心,却对金茉两人十分冷漠
2020/03/17 国漫
古巴咖啡 Cubita琥爵咖啡 独特的加勒比海风味咖啡
2021/03/06 新手入门
模拟SQLSERVER的两个函数:dateadd(),datediff()
2006/10/09 PHP
执行、获取远程代码返回:file_get_contents 超时处理的问题详解
2013/06/25 PHP
js限制checkbox勾选的个数以及php获取多个checkbbox的方法深入解析
2013/07/18 PHP
java微信开发之上传下载多媒体文件
2016/06/24 PHP
PHP实现的只保留字符串首尾字符功能示例【隐藏部分字符串】
2019/03/11 PHP
宝塔面板在NGINX环境中TP5.1如何运行?
2021/03/09 PHP
基于JQuery框架的AJAX实例代码
2009/11/03 Javascript
js交换排序 冒泡排序算法(Javascript版)
2014/10/04 Javascript
深入理解node exports和module.exports区别
2016/06/01 Javascript
javascript动画之模拟拖拽效果篇
2016/09/26 Javascript
原生js获取浏览器窗口及元素宽高常用方法集合
2017/01/18 Javascript
Node.js 8 中的重要新特性
2017/06/28 Javascript
nodejs动态创建二维码的方法
2017/08/12 NodeJs
使用vue-cli编写vue插件的方法
2018/02/26 Javascript
原生javascript AJAX 三级联动的实现代码
2018/05/04 Javascript
vue-cli3.0如何使用CDN区分开发、生产、预发布环境
2018/11/22 Javascript
JS实现鼠标拖拽盒子移动及右键点击盒子消失效果示例
2019/01/29 Javascript
手挽手带你学React之React-router4.x的使用
2019/02/14 Javascript
详解用vue2.x版本+adminLTE开源框架搭建后台应用模版
2019/03/15 Javascript
详释JavaScript执行环境与执行栈
2019/04/02 Javascript
详解Vue3.0 前的 TypeScript 最佳入门实践
2019/06/18 Javascript
详解JavaScript中精度失准问题及解决方法
2020/02/04 Javascript
Python实现的对本地host127.0.0.1主机进行扫描端口功能示例
2019/02/15 Python
Python使用LDAP做用户认证的方法
2019/06/20 Python
对python中的控制条件、循环和跳出详解
2019/06/24 Python
python zip()函数使用方法解析
2019/10/31 Python
python 安装教程之Pycharm安装及配置字体主题,换行,自动更新
2020/03/13 Python
Kmeans均值聚类算法原理以及Python如何实现
2020/09/26 Python
CSS3实现点击放大的动画实例代码
2017/02/27 HTML / CSS
高三家长寄语
2014/04/03 职场文书
投标人法定代表人授权委托书格式
2014/09/28 职场文书
2014年科普工作总结
2014/12/06 职场文书
管理者们如何制定2019年的工作计划?
2019/07/01 职场文书
详解python中[-1]、[:-1]、[::-1]、[n::-1]使用方法
2021/04/25 Python