1. 位运算符是在数字底层(即二进制数)进行操作的。JavaScript将数字存储为64位浮点数, 但所有按位运算都以32位二进制数执行; 在执行位运算之前, JavaScript将数字转换为32位有符号整数; 执行按位操作后, 结果将转换回64位JavaScript数。
2. 重温整数
2.1. JavaScript数字有两种类型, 即有符号数字(允许用正数和负数)和无符号数字(只允许用正数)。
2.2. 所有数字字面量都默认存储为有符号数字。只有JavaScript的位运算符才能创建无符号数字。
2.3. JavaScript数字在进行位运算时, 是32位整数(非64位浮点数)。
2.4. 有符号整数使用31位储存数字。用第32位储存符号, 0表示正数, 1表示负数。整数的取值范围从-2147483648到2147483647。
2.5. 无符号整数把最后一位也用作储存数字。在这种模式中, 第32位不表示数字的符号, 而是值。由于这个额外的位, 无符号整数的数值范围为0到4294967295。
3. 位运算NOT
3.1. 位运算NOT由否定号(~)表示, 对数按位取反, 包括符号位。
3.2. 例如:
var iNum1 = 25; // 25等于00000000000000000000000000011001
var iNum2 = ~iNum1; // 转换为11111111111111111111111111100110
alert(iNum2); // 输出"-26"
3.3. 位运算NOT实质上是对数字求负, 然后减1, 因此25变-26。用下面的方法也可以得到同样的方法:
var iNum1 = 25;
var iNum2 = -iNum1 -1;
alert(iNum2); //输出 -26
3.4. 例子
3.4.1. 代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<title>位运算NOT</title>
</head>
<body>
<script type="text/javascript">
/**
* 0000 0000 0000 0000 0000 0000 0000 0110
* ~
* 1111 1111 1111 1111 1111 1111 1111 1001
* 1111 1111 1111 1111 1111 1111 1111 1000
* 1000 0000 0000 0000 0000 0000 0000 0111
*/
var a = 6;
var b = ~a;
/**
* 1000 0000 0000 0000 0000 0000 0000 0110
* 1111 1111 1111 1111 1111 1111 1111 1001
* 1111 1111 1111 1111 1111 1111 1111 1010
* ~
* 0000 0000 0000 0000 0000 0000 0000 0101
*/
var c = -6;
var d = ~c;
document.write('a = ' + a + '<br />');
document.write('~a = ' + b + '<br />');
document.write('c = ' + c + '<br />');
document.write('~c = ' + d);
</script>
</body>
</html>
3.4.2. 效果图
3. 位运算AND
3.1. 位运算AND由和号(&)表示, 直接对数字的二进制形式进行运算。它把每个数字中的数位对齐, 然后用下面的规则对同一位置上的两个数位进行AND运算, 包括符号位。
3.2. 例子
3.2.1. 代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<title>位运算AND</title>
</head>
<body>
<script type="text/javascript">
/**
* 0000 0000 0000 0000 0000 0000 0000 0110
* &
* 0000 0000 0000 0000 0000 0000 0000 0010
*
* 0000 0000 0000 0000 0000 0000 0000 0010
*/
var a = 6;
var b = a & 2;
/**
* 1000 0000 0000 0000 0000 0000 0000 0110
* 1111 1111 1111 1111 1111 1111 1111 1001
* 1111 1111 1111 1111 1111 1111 1111 1010
* &
* 0000 0000 0000 0000 0000 0000 0000 0010
*
* 0000 0000 0000 0000 0000 0000 0000 0010
*/
var c = -6;
var d = c & 2;
document.write('a = ' + a + '<br />');
document.write('a & 2 = ' + b + '<br />');
document.write('c = ' + c + '<br />');
document.write('c & 2 = ' + d);
</script>
</body>
</html>
3.2.2. 效果图
4. 位运算OR
4.1. 位运算OR由符号(|)表示, 直接对数字的二进制形式进行运算。它把每个数字中的数位对齐, 然后用下面的规则对同一位置上的两个数位进行OR运算, 包括符号位。
4.2. 例子
4.2.1. 代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<title>位运算OR</title>
</head>
<body>
<script type="text/javascript">
/**
* 0000 0000 0000 0000 0000 0000 0000 0110
* |
* 0000 0000 0000 0000 0000 0000 0000 0001
*
* 0000 0000 0000 0000 0000 0000 0000 0111
*/
var a = 6;
var b = a | 1;
/**
* 1000 0000 0000 0000 0000 0000 0000 0110
* 1111 1111 1111 1111 1111 1111 1111 1001
* 1111 1111 1111 1111 1111 1111 1111 1010
* |
* 0000 0000 0000 0000 0000 0000 0000 0001
*
* 1111 1111 1111 1111 1111 1111 1111 1011
* 1111 1111 1111 1111 1111 1111 1111 1010
* 1000 0000 0000 0000 0000 0000 0000 0101
*/
var c = -6;
var d = c | 1;
document.write('a = ' + a + '<br />');
document.write('a | 1 = ' + b + '<br />');
document.write('c = ' + c + '<br />');
document.write('c | 1 = ' + d);
</script>
</body>
</html>
4.2.2. 效果图
5. 位运算XOR
5.1. 位运算XOR由符号(^)表示, 直接对数字的二进制形式进行运算。它把每个数字中的数位对齐, 然后用下面的规则对同一位置上的两个数位进行XOR运算, 包括符号位。
5.2. 例子
5.2.1. 代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<title>位运算XOR</title>
</head>
<body>
<script type="text/javascript">
/**
* 0000 0000 0000 0000 0000 0000 0000 0110
* ^
* 0000 0000 0000 0000 0000 0000 0000 0010
*
* 0000 0000 0000 0000 0000 0000 0000 0100
*/
var a = 6;
var b = a ^ 2;
/**
* 1000 0000 0000 0000 0000 0000 0000 0110
* 1111 1111 1111 1111 1111 1111 1111 1001
* 1111 1111 1111 1111 1111 1111 1111 1010
* ^
* 0000 0000 0000 0000 0000 0000 0000 0010
*
* 1111 1111 1111 1111 1111 1111 1111 1000
* 1111 1111 1111 1111 1111 1111 1111 0111
* 1000 0000 0000 0000 0000 0000 0000 1000
*/
var c = -6;
var d = c ^ 2;
/**
* 1000 0000 0000 0000 0000 0000 0000 0110
* 1111 1111 1111 1111 1111 1111 1111 1001
* 1111 1111 1111 1111 1111 1111 1111 1010
* ^
* 1000 0000 0000 0000 0000 0000 0000 0010
* 1111 1111 1111 1111 1111 1111 1111 1101
* 1111 1111 1111 1111 1111 1111 1111 1110
*
* 0000 0000 0000 0000 0000 0000 0000 0100
*/
var e = c ^ -2;
document.write('a = ' + a + '<br />');
document.write('a ^ 2 = ' + b + '<br />');
document.write('c = ' + c + '<br />');
document.write('c ^ 2 = ' + d + '<br />');
document.write('c ^ -2 = ' + e);
</script>
</body>
</html>
5.2.2. 效果图
6. 左移运算
6.1. 左移运算由两个小于号表示(<<)。它把数字中的所有数位向左移动指定的数量, 不包括符号位, 然后用0填充这些空位。
6.2. 例子
6.2.1. 代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<title>有符号左移运算</title>
</head>
<body>
<script type="text/javascript">
/**
* -1
* 1000 0000 0000 0000 0000 0000 0000 0001
* 1111 1111 1111 1111 1111 1111 1111 1110
* 1111 1111 1111 1111 1111 1111 1111 1111
* <<1
* 1111 1111 1111 1111 1111 1111 1111 1110
* 1111 1111 1111 1111 1111 1111 1111 1101
* 1000 0000 0000 0000 0000 0000 0000 0010
*/
var a = -1;
var b = a << 1;
/**
* 64
* 0000 0000 0000 0000 0000 0000 0100 0000
* <<2
* 0000 0000 0000 0000 0000 0001 0000 0000
*/
var c = 64;
var d = c << 2;
/**
* -64
* 1000 0000 0000 0000 0000 0000 0100 0000
* 1111 1111 1111 1111 1111 1111 1011 1111
* 1111 1111 1111 1111 1111 1111 1100 0000
* <<2
* 1111 1111 1111 1111 1111 1111 0000 0000
* 1111 1111 1111 1111 1111 1110 1111 1111
* 1000 0000 0000 0000 0000 0001 0000 0000
*/
var e = -64;
var f = e << 2;
document.write('a = ' + a + '<br />');
document.write('a << 1 = ' + b + '<br />');
document.write('c = ' + c + '<br />');
document.write('c << 2 = ' + d + '<br />');
document.write('e = ' + e + '<br />');
document.write('e << 2 = ' + f);
</script>
</body>
</html>
6.2.2. 效果图
7. 有符号右移运算
7.1. 有符号右移运算符由两个大于号表示(>>)。它把32位数字中的所有数位整体右移, 同时保留该数的符号(正号或负号), 用符号位的值填充这些空位。
7.2. 例子
7.2.1. 代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<title>有符号右移运算</title>
</head>
<body>
<script type="text/javascript">
/**
* -1
* 1000 0000 0000 0000 0000 0000 0000 0001
* 1111 1111 1111 1111 1111 1111 1111 1110
* 1111 1111 1111 1111 1111 1111 1111 1111
* >>1
* 1111 1111 1111 1111 1111 1111 1111 1111
*/
var a = -1;
var b = a >> 1;
/**
* 64
* 0000 0000 0000 0000 0000 0000 0100 0000
* >>2
* 0000 0000 0000 0000 0000 0000 0001 0000
*/
var c = 64;
var d = c >> 2;
/**
* -64
* 1000 0000 0000 0000 0000 0000 0100 0000
* 1111 1111 1111 1111 1111 1111 1011 1111
* 1111 1111 1111 1111 1111 1111 1100 0000
* >>2
* 1111 1111 1111 1111 1111 1111 1111 0000
* 1111 1111 1111 1111 1111 1111 1110 1111
* 1000 0000 0000 0000 0000 0000 0001 0000
*/
var e = -64;
var f = e >> 2;
document.write('a = ' + a + '<br />');
document.write('a >> 2 = ' + b + '<br />');
document.write('c = ' + c + '<br />');
document.write('c >> 2 = ' + d + '<br />');
document.write('e = ' + e + '<br />');
document.write('e >> 2 = ' + f);
</script>
</body>
</html>
7.2.2. 效果图
8. 无符号右移运算
8.1. 无符号右移运算符由三个大于号(>>>)表示, 它将无符号32位数的所有数位整体右移, 不保留符号位, 用0填充所有空位。
8.2. 例子
8.2.1. 代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8" />
<title>无符号右移运算</title>
</head>
<body>
<script type="text/javascript">
/**
* -1
* 1000 0000 0000 0000 0000 0000 0000 0001
* 1111 1111 1111 1111 1111 1111 1111 1110
* 1111 1111 1111 1111 1111 1111 1111 1111
* >>>1
* 0111 1111 1111 1111 1111 1111 1111 1111
*/
var a = -1;
var b = a >>> 1;
document.write('a = ' + a + '<br />');
document.write('a >>> 1 = ' + b);
</script>
</body>
</html>
8.2.2. 效果图