ビット演算子のJavaScript

   I.ビット演算子   

処理ビット演算子32ビット

任意の数値、オペランドの演算が32ビットに変換され、結果は、JavaScriptの数に換算バックあります

直接計算、7事業者の合計のためのバイナリビット演算子:

OR(又は):記号| 2ビットが0である場合、結果は1それ以外の場合は0です。

オペレータ(及び):&シンボル の2ビットが1であれば、その結果は、そうでなければ0、1です。

ノーオペレーション(ない):〜シンボルバイナリビット反転のために、

排他的論理和演算(XOR):^記号は、 2つのビットが同じでない場合、結果は、そうでなければ0として、1です。

左シフト演算(左シフト):シンボル<< 

右シフト演算(右シフト):シンボル>> 

符号ビット(ゼロ埋め右シフト)との算術右シフト:シンボル>>> 

 

   第二に、ビット演算子の紹介  

ビット演算子が直接各ビット(ビット)アドレス、それは根本的な操作です。

メリット:高速動作。

欠点:非常に直感的な操作、多くの場合はそれ以外の場合は、コードおよびトラブルシューティングを理解するのは難しいだろう、使用することはできません。

オペレータが整数でない場合はビット処理演算子は、整数のみに作用するが、それは自動的に整数演算に変換されます

JavaScriptの内部に、値は64ビット浮動小数点数として記憶されるが、ビット操作を行う場合、32ビット符号付き整数演算が行われており、返される整数値は、32ビット符号付きです。

 

   第三に、あなたのオペレータ特性   

(A)及び算術演算又は

2桁ごとの演算子の比較

OR長い11があるとして2ビットが、1が返され、そうでなければ0を返します。

そして操作:2ビットであれば0が存在するように、それはそうでなければ1を返し、0を返します。

0 | 3。     // 3 
0&3;   // 0 
3 | 4     // 7 
3&4    // 0

「操作」00(即ち、0)となる。上記式3において0は、それぞれ、バイナリ0と3の形態、00及び11において、「OR演算」11(即ち、3)であろう。

「操作」0(すなわち、0)となる。上記式3及び4、3、4バイナリ形式、それぞれ11および001において、「OR演算」111(すなわち、7)であろう。

注意:

ビット演算は、整数、小数遭遇した場合にのみ有効で、小数部は整数部分のみを残して、になります。

そう0除去小数部の数に相当する小数と「OR」、すなわち丸い数字であろう。の(これは、バイナリ32ビット整数番号2147483648の最大値よりもやり方を丸めるには適用されません)

2.7 | 0; // 2 
-3.5 | 0;  // -3
 
2147483647.4 | 0;   // 2147483647 
2147483648.4 | 0;   // -2147483648 
2147483649.4 | 0;   // -2147483647   

 

(B)ノー・オペレーション

何も操作:各ビットが(0〜1まで、すなわち、0、1)とは反対になって、作動機構は、非常に明確に理解するのは時々困難ではないではありません。

〜3   // 4

この式において、3「ノーオペレーション」の後に、それは-4でした。

その理由は、ビット操作、内部のJavaScriptすべてのオペレータは、32ビットのバイナリ整数に変換して計算されます。

3 在JavaScript内部是 0000,0000,0000,0000,0000,0000,0000,0011(共32位),否运算后得到11111111111111111111111111111100 ,由于第一位是  1,所以这个数是负数。JavaScript内部采取补码形式表示负数,即需要将这个数减去1,再取一次反,然后加上符号,才能得到这个负数对应的十进制值。这个数减去1等于  11111111111111111111111111111011 ,再取一次反得到 000000000000000000000000000000100,加上负号就是 -4。

这个过程这样计算未免太过麻烦,也可以简单记忆成,一个数与自身的取反值相加,等于 -1。(3的取反值为-4,-3的取反值是2)

注意:

1、对一个整数连续两次 ‘否运算’,可以得到它自身;

2、所有的位运算只对整数有效。否运算遇到小数时,也会将小数部分舍去,只保留整数部分,所以,对一个小数连续两次否运算,就可以达到取整的效果。

3、使用否运算取整,是所有取整方法中最快的一种。

~ -3 // 2
~~3 // 3
~~2.9 // 2
~~47.11 // 47
~~1.9999 // 1
~~3 // 3

1、字符串类型:对字符串进行否运算,JavaScript引擎会先调用 Number 函数,将字符串转为数值。

下面例子相当于  ~Number('011')

~'011' // -12
~'42 cats' // -1
~'0xcafebabe' // 889275713
~'deadbeef' // -1

下面例子相当于  ~~Number('011')

~~'011'; // 11
~~'42 cats'; // 0
~~'0xcafebabe'; // -889275714
~~'deadbeef'; // 0

2、数值的处理是:超出 32位的整数将会被截去超出的位数,NaN 和 Infinity 转为 0;

3、对于其他类型的参数,否运算也是先用 Number 转为数值,然后再进行处理

~~[] // 0
~~NaN // 0
~~null // 0

 

(三)异或运算

异或运算:在两个二进制位不同时返回 1,相同时返回 0;

0 ^ 3 // 3

在这个表达式中,0 的二进制形式是 00,3的二进制形式是 11,它们每一个二进制位都不同,所以得到 11(即3)

异或运算特殊运用:

连续对两个数 a和b 进行 3 次异或运算(a^b, b^a, a^b),可以互换他们的值。这意味着,使用 异或运算 可以在不引用临时变量的前提下,互换两个变量的值。

 运用异或运算互换两个变量的值。这是互换变量值最快的方法。

var a = 10;
var b = 99;
a ^= b, b ^= a, a ^= b;
a // 99
b // 10

通过引用临时变量,互换两个变量的值。

var a = 10;
var b = 99;
var c;
c=a;a=b;b=c;
console.log(a) // 99
console.log(b) // 10

 异或运算也可以用来取整,与 0 一起运算

12.9 ^ 0 // 12

 

(四)左移运算符

左移运算符:表示将一个数的二进制值向左移动指定的位数,在尾部补 0,即乘以 2 的指定次方(最高位即符号位不参加移动)

// 4 的二进制形式为100,
// 左移一位为1000(即十进制的8)
// 相当于乘以2的1次方
4 << 1
// 8
-4 << 1
// -8

这个例子中, -4左移一位得到 -8,是因为 -4 的二进制形式是 11111111111111111111111111111100 ,左移一位后得到 11111111111111111111111111111000,把这个数字转换为十进制(减去1后取反,再加上符号)结果为 -8;

如果左移 0 位,就相当于将该数值转换为 32位整数,等同于取整,对于正数和负数 都有效。

13.5 << 0
// 13
-13.5 << 0
// -13

左移运算用于二进制取值非常方便:

实例:

使用左移运算符,将颜色的RGB值转换为 HEX值


var colo {r: 186, g: 218, b: 85};
// RGB to HEX
// (1 << 24)的作用为保证结果是6位数
var rgb2hex = function(r, g, b) {
  return '#' + ((1 << 24) + (r << 16) + (g << 8) +
.toString(16) .substr(1); }rgb2hex(color.r,color.g,color.b) // "#bada55"

 

(五)右移运算符

右移运算符:表示将一个数的二进制值向右移动指定的位数,头部补 0,即除以 2 的指定次方(最高位即符号位不参与移动)

4 >> 1

 

 在这个例子中,因为 4的二进制形式为 00000000000000000000000000000100,向右移动一位之后(在头部补 0 ),得到 00000000000000000000000000000010,即为十进制的 2。

-4 >> 1

 在这个例子中,-4 的二进制形式为 11111111111111111111111111111100,右移一位,头部补 1(二进制采取补码的形式表示负数),得到 11111111111111111111111111111100,即为十进制的 -2。

使用右移运算符模拟 2 的倍数

5 >> 1
// 相当于 5 / 2 = 2,101转换为10,即为2
21 >> 2
// 相当于 21 / 4 = 5,10101转换为101,即为5
21 >> 3
// 相当于 21 / 8 = 2,10101转换为10,即为2
21 >> 4
// 相当于 21 / 16 = 1,10101转换为1,即为1

 

(六)带符号位的右移运算符(>>>)

带符号的右移运算符:表示将一个数的二进制形式向右移动,包括符号位也参与移动,头部补 0。

所以,该运算总是得到正数。对于正数,该运算的结果与右移运算符(>>)完全一致,区别只要在于负数。

4>>>1

-4>>>1

在这个例子中,-4 的二进制形式为 11111111111111111111111111111100,带符号位的右移一位,头部补0,得到 0111111111111111111111111111110,即为十进制的 2147483646。

这个运算实际上将一个值转为 32 位无符号整数。

查看一个负整数在计算机内部的储存形式,最快的方法就是使用这个运算符。

-1>>>1

-1 作为 32 位整数时,内部储存形式使用无符号正数格式解读,值为4294967295(即 ( 2^32)-1,等于11111111111111111111111111111111)

 

   四、设置对象属性开关   

位运算符可以用作设置对象属性的开关

加定某个对象有四个开关,每个开关都是一个变量。那么就可以设置一个四位的二进制数,它的每个位都对应一个开关。

var flag_A = 1; // 0001
var flag_B = 2; // 0010
var flag_C = 4; // 0100
var flag_D = 8; // 1000

上面代码设置 A、B、C、D四个开关,每个开关分别占了有一个二进制位。然后,就可以使用 ‘与运算’ 检验,当前设置是否打开了指定开关。

var flags = 5; // 二进制的0101
if (flags & FLAG_C) {
 // ...
}
// 0101 & 0100 => 0100 => true

上面代码检验是否打开了 开关C。如果打开,返回 true,否则返回 false。

现在假设 需要打开ABD三个开关,可以构建一个掩码变量

var mask = FLAG_A | FLAG_B | FLAG_D;
// 0001 | 0010 | 1000 => 1011

上面代码对A B D三个变量进行 ‘或运算’,得到掩码值为二进制的1011。有了掩码,‘或运算’ 可以确保打开指定的开关。

flags = flags | mask;

“与运算” 可以将当前设置中凡是与开关设置不一样的项,全部关闭

flags = flags & mask;

“异或运算” 可以切换(toggle)当前设置,即第一次执行可以得到当前设置的相反值,再执行一次,可以得到原来的值。

flags = flags ^ mask;

“否运算”可以翻转当前设置,即原设置为 0 ,运算后变为 1 ;原设置为 1 ,运算后变为 0;

flags = ~flag

 

 

おすすめ

転載: www.cnblogs.com/nyw1983/p/11880976.html