原文:js中位运算的运用

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

按位与(&)

&&运算符我们都知道,只有两个都为真,结果才为真。&道理是一样的,只有两个数的值为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。

总结

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

js中位运算的运用的更多相关文章

  1. js的位运算(其它语言也通用)

    左移运算符(<<) 该运算符有2个运算数,a<<b,将a左移相当于a乘以2的b次方,2个运算符要求是整数,或可以转换成整数的. 如:1<<2 =4 "1& ...

  2. LeetCode解题中位运算的运用

    位运算是我最近才开始重视的东西,因为在LeetCode上面刷题的时候发现很多题目使用位运算会快很多.位运算的使用包含着许多技巧(详细可以参考http://blog.csdn.net/zmazon/ar ...

  3. java中位运算

    1byte(字节)=8bit(比特) 1 0 0 0 0 0 0 0 1   2进制的1的原码 反码 补码 0 0 0 0 0 0 0 0   2进制的0的原码 反码 补码 -1 1 0 0 0 0 ...

  4. C++中位运算

    简介 1 位逻辑运算符: & (位   “与”)  and ----------------- 2个都为1 才是1-----------0^0 = 0 , 0^1 = 0,  1^0 = 0  ...

  5. java中位运算和移位运算详解

    一.位运算 (1)按 位 与 & 如果两个相应的二进制形式的对应的位数都为1,则结果为1,记为同1为1,否则为0.首先我们看一下对正数的运算        分别看一下正数和负数的具体运算步骤 ...

  6. 搞懂js中小数运算精度问题原因及解决办法

    js小数运算会出现精度问题 js number类型 JS 数字类型只有number类型,number类型相当于其他强类型语言中的double类型(双精度浮点型),不区分浮点型和整数型. number类 ...

  7. js中浮点型运算 注意点

    先看张图: 这是一个JS浮点数运算Bug,导致我树状图,数据合计不正确,,,,,,两个小数相加,出来那么多位小数 (这是修该之后的) 网上找到以下解决方式: 方法一:有js自定义函数   <sc ...

  8. java中位运算^,&,<<,>>,<<<,>>>总结

    1.^(亦或运算) ,针对二进制,相同的为0,不同的为1 public static void main(String[] args) { System.out.println("2^3运算 ...

  9. C语言中位运算异或“∧”的作用

    1.概念异或运算符"∧"也称XOR运算符.它的规则是若参加运算的两个二进位同号,则结果为0(假):异号则为1(真).即 0∧0=0,0∧1=1, 1^0=1,1∧1=0.运算    ...

随机推荐

  1. 返璞归真 asp.net mvc (1) - 添加、查询、更新和删除的 Demo

    原文:返璞归真 asp.net mvc (1) - 添加.查询.更新和删除的 Demo [索引页] [源码下载] 返璞归真 asp.net mvc (1) - 添加.查询.更新和删除的 Demo 作者 ...

  2. php调用webservice的几种方法

    原文:php调用webservice的几种方法 1.WSDL模式: $soap = new SoapClient("http://192.168.6.69:8899/Service1.asm ...

  3. C/S通信模型和相关技术要点

    差点儿全部的项目中,都会涉及到client和服务端.而client与server之间的通信又是一个非经常见但又有须要问题的技术问题. 首先,连接方式有长连接和短连接.先看看概念. 长连接短连接仅仅是一 ...

  4. c# 判断字符是否是全角, 获取字符串的字节数 , 获取字符串指定长度字节数的字符串

    1 Encoding.Default.GetByteCount(checkString);  =2 全角 =1 半角 /// <summary> /// 获取字符串的字节长度 /// &l ...

  5. C++它tinyXML使用

    tinyXML一个非常好的操作C++图书馆,文件不大,但方法非常丰富.和apache的Dom4j能够披靡啊! 习惯了使用java类库的我看到这么丰富的c++类库,非常高兴!它使用非常easy.仅仅须要 ...

  6. 从电商秒杀与抢购谈Web系统大规模并发

    从电商秒杀与抢购谈Web系统大规模并发 http://www.iamlintao.com/4242.html 一.大规模并发带来的挑战 在过去的工作中,我曾经面对过5w每秒的高并发秒杀功能,在这个过程 ...

  7. SQL Server AlwaysOn中的几个误区

    原文:SQL Server AlwaysOn中的几个误区 AlwaysOn自SQL Server2012之后已经发布很久了,最近我在给一些客户做咨询的时候经常被问起是不是应该使用AlwaysOn,从客 ...

  8. 百度云BAE3.0 的ssh构造(本机ssh项目迁移到BAE3.0)

    依据百度云的java部署文档进行部署 http://developer.baidu.com/wiki/index.php?title=docs/cplat/bae/java 做例如以下改动,然后把项目 ...

  9. Java操作memcached(一)

    Memcached事实上,两次Hash算法    第一次hash算法被用于定位Memcached示例    第二次hash算法是底部HashMap中间hash算法 Hash算法      1.依据余数 ...

  10. 采用CSS3 Media Query技术适应Android平板屏幕分辨率和屏幕像素密度

    采用HTML5在开发移动应用程序满足各种需求Android分辨率和屏幕的平板设备密度,这是非常麻烦的过程,最终的解决方案是使用css media query,匹配相同的时间分辨率和屏幕像素密度.上进行 ...