「JavaScript/ビット演算」の版間の差分

削除された内容 追加された内容
編集の要約なし
15 行
* << 左シフト
* >> 右シフト
* >>> 符号なし右シフト演算子
* ~ 1の補数を得る
 
23 行
* |= ビットごとのOR演算をして代入
* ^= ビットごとの排他的ORをして代入
* >>= 左シフトして代入
* <<= 右シフトして代入
* >>>= 符号なし右シフト演算子
 
JavaScriptでビット演算を行ううえで注意すべきことは、ビット演算を行う前にNumber型の値を一度32ビットの整数に変換をする事である。
これは、現在のプロセッサが32ビットの整数型を扱いやすい事を考えられて作られていると思われる。
 
ビット演算を既に理解している場合はこれ以降の解説は必要ないと思われるが、プログラミング初学者のために以降はビット演算の基本的な解説を行う
31 ⟶ 34行目:
=== 2進法の表記法 ===
 
コンピューターは、その回路構成を単純にするため通常内部的に2進法を用いており通常いるため、2進で計算できるものはこちらで計算したほうが高速であに動作するため
、通常こちらを利用する。
二進法とは、10進法とは違い2の倍数で桁上げを行う数の表記法である。理解のために、10進法と、2進、3進、4進法での数の表記の対応表、さらに8進法」、16進法の表記を載せる。
 
{| class="wikitable"
10進法 1 2 3 4 5 6 7 8 9 10
|- align="right"
! 10進法
| 1
| 2
| 3
| 4
| 5
| 6
| 7
| 8
| 9
| 10
| 11
| 12
| 13
| 14
| 15
| 15
| 17
| 18
| 19
| 20
|- align="right"
! 2進法
| 1
| 10
| 11
| 100
| 101
| 110
| 111
| 1000
| 1001
| 1010
| 1011
| 1100
| 1101
| 1111
| 10000
| 10001
| 10010
| 10011
| 10100
| 10101
|- align="right"
! 3進法
| 1
| 2
| 10
| 11
| 12
| 20
| 21
| 22
| 100
| 101
| 110
| 111
| 1000
| 1001
| 1010
| 1011
| 1100
| 1101
| 1110
| 1111
|- align="right"
! 4進法
| 1
| 2
| 3
| 10
| 11
| 12
| 13
| 20
| 21
| 22
| 23
| 30
| 31
| 32
| 33
| 100
| 101
| 102
| 103
| 110
|- align="right"
! 8進法
| 1
| 2
| 3
| 4
| 5
| 6
| 7
| 10
| 11
| 12
| 13
| 14
| 15
| 16
| 17
| 20
| 21
| 22
| 23
| 24
|- align="right"
! 16進法
| 1
| 2
| 3
| 4
| 5
| 6
| 7
| 8
| 9
| a
| b
| c
| d
| e
| f
| 10
| 11
| 12
| 13
| 14
|}
 
* [[w:二進記数法]]
2進法 1 10 11 100 101 110 111 1000 1001 1010
 
2進法は、大きな数になるほど桁数が増えるため、記述を短く簡単に抑えるため通常は16進法を使って記述を行う。
3進法 1 2 10 11 12 20 21 22 100 101 102
16進法では、9を超える数には順にa,b,c,d,e,fと記号を振ってあり1~15までを一桁で表せる。
 
16進法を使用する場合には、数字の前に0xを付けて表記する。
4進法 1 2 3 10 11 12 13 20 21 22
(C言語では8進数での表記も可能であるが16進法ほど利用されていないため、JavaScriptの標準仕様では採用されていない)
 
* [[w:二進記数法]]
 
=== 補数 ===
56 ⟶ 192行目:
 
<nowiki>
1 << 2; // 1が2ビット左シフトするため、2進数で「100」つまり4が返る
130xd >> 2; // 10進法では13。2進法で「1101」からこれを右シフトして2進数で「11」、つまり10進法の3が返る </nowiki>
 
JavaScriptではビットシフトを行っても正負の記号は保存される。
しかし、符号なし右シフト演算子(>>>)を使った場合にはこの結果は異なる。
<nowiki>
-10 >> 1; // -5が返る
-10 >>> 1; // 2147483643が返る </nowiki>
これは、先頭にある正負の記号を表すビットもシフトさせるためである。
 
これは、先頭にある正負の記号を表すビットもシフトさせるためである。
 
=== 論理演算 ===
74 ⟶ 210行目:
論理積の結果を表に表すと次の様になっている。
 
{| class="wikitable"
論理積
|- align="center"
1 1 1
! 命題P
1 0 0
! 命題Q
0 1 0
! P & Q
0 0 1
|- align="center"
| 1
| 1
| 1
|- align="center"
| 1
| 0
| 0
|- align="center"
| 0
| 1
| 0
|- align="center"
| 0
| 0
| 1
|}
 
論理積の演算子は"&"であるから、実際の演算を行うと次の様になる。
<nowiki>
1 & 1; // 1が返る
1 & 0; // 0が返る
0 & 1; // 0が返る
0 & 0; // 0が返る </nowiki>
 
同じように、論理和、排他的論理和の計算結果を挙げると次の様になっている。
<nowiki>
// 論理和の演算
1 | 1; // 1が返る
1 | 0; // 1が返る
0 | 1; // 1が返る
0 | 0; // 0が返る
 
// 排他的論理和の演算
1 ^ 1; // 0が返る
1 ^ 0; // 1が返る
0 ^ 1; // 0が返る
0 ^ 0; // 1が返る </nowiki>
 
* [[w:ブール代数]]
* [[w:ビット演算]]
 
これらの演算はビットごとに行われるため、通常の四則演算とは違った考え方で結果を捉える必要がある。
105 ⟶ 261行目:
同じように2も2進数では「10」と表記されるため、このビット積「7&2」は次の様に、ビットごとの計算が行われるため次の様になる
 
{| class="wikitable"
1 1 1
|- align="center"
 
! 数字
0 1 0
! 3ビット目
! 2ビット目
! 1ビット目
|- align="center"
! 7
| 1
| 1
| 1
|- align="center"
! 2
| 0
| 1
| 0
|- align="center"
! 5
| 1
| 0
| 1
|}
 
1 0 1
<nowiki>
7 & 2; // 2進数では111 & 010 、この結果は2進数で「101」なので「5」である </nowiki>
 
この性質を利用すればビット積で末尾1ビットを残すことで、奇数、偶数の判別が可能である
この様な操作をビットマスクと呼ぶ。
<nowiki>
num & 1; // 1なら奇数、0なら偶数 </nowiki>
 
0となった値を1にするにはビット和を利用する。
124 ⟶ 299行目:
(2進法よりも簡潔な記述を行うため、実際のコードで16進法で記述を行う)
 
この仕掛けを利用すれば、一つの数字データに複数のデータを格納できる事に気づく
例えば、コンピュータ内部で色を扱う場合の例で、数値型データの中から、32ビットの数値を8ビットごとに区切ってそれぞれ、透明度、赤、緑、青を格納している。
(これをARGB系と呼んでいる)
134 ⟶ 309行目:
*/
function getColor( color ){
return {
a:(color & 0xff000000)>>24,
r:(color & 0x ff00000xff0000)>>16,
g:(color & 0xff00)>>8,
b:color & 0xff
};
}
getColor( color ).r; // 赤を取り出し </nowiki>
 
* [[w:ブール代数]]
* [[w:ビット演算]]
 
実際にはビット演算には他にも数多くのテクニックが存在するが、今回のその解説は省略した。
JavaScriptでのプログラミングでは、スクリプトの評価の方が処理時間をとっているためC言語などでの高速化手法としては使われない
そのため、InternetExplolerでActiveXオブジェクトとのデータのやりとりなど、他の言語環境とのデータのやり取りに使われることもあるが、実際にこれらの演算手法を使う機会は他の言語より少ない。
基本的には、配列などの他の方法を使うよりこちらの方が鮮やかに記述できる場合に利用すべきである。