ビット演算・ビットシフト

  • 論理演算子と住み分けが微妙だけどとりあえずどっちかに書いてあればいいです。
例題で1,2,4,8…と数が増えていくのは2進数で表した時に0001,0010,0100,1000,…と左に1ビットずつシフトしていっているから。

Java

ビット演算子

AND

二つの変数を比較し1が一致するbitを取得します
論理演算子にも&があるので注意です
  • 論理演算子での&の使用例
    • if(true & true)等
    • 両方がtrueの時、真である。
int b = 0x55;
int c = 0x0f;
System.out.println("  b:"+Integer.toBinaryString(b));
System.out.println("  c:"+Integer.toBinaryString(c));
System.out.println("b&c:"+Integer.toBinaryString(b&c));
//実行結果

   b:01010101
   c:00001111
------------
b&c:00000101
※結果を解りやすくするために0を追加した8bitの範囲内で表示しています。

OR

二つの変数を比較し1が存在する全てのbitを取得します
論理演算子にも|があるので注意です
  • 論理演算子の使用例
    • if(true | false){ //true...}else{//false...}
    • 片方でもtrueなら、真である。
int b = 0x55;
int c = 0x0f;
System.out.println("  b:"+Integer.toBinaryString(b));
System.out.println("  c:"+Integer.toBinaryString(c));
System.out.println("b&c:"+Integer.toBinaryString(b|c));
//実行結果
   b:01010101
   c:00001111
--------------
b&c:01011111
※結果を解りやすくするために0を追加した8bitの範囲内で表示しています。

NOT

一つの変数からその正反対のbitを取得します
論理演算子に~(チルダ)はありません。
int b = 0x55;
System.out.println("b:"+Integer.toBinaryString(b));
System.out.println("b:"+Integer.toBinaryString(~b));
//実行結果
b:01010101
b:10101010
※結果を解りやすくするために0を追加した8bitの範囲内で表示しています。

XOR

二つの変数から片方にしか1がない場合のみ1を取得します
論理演算子にも^(カレット)があるので注意です
  • 論理演算子^の使用例
    • if(true ^ false){//true...}
    • 両方の型がboolean型かつ異なっている時、真である。
int b = 0x55;
int c = 0x0f;
System.out.println("  b:"+Integer.toBinaryString(b));
System.out.println("  c:"+Integer.toBinaryString(c));
System.out.println("b^c:"+Integer.toBinaryString(b^c));
※結果を解りやすくするために0を追加した8bitの範囲内で表示しています。

ビットシフト

二進数で右に一つシフトした時の数値は1/2になり、左に一つシフトした時2倍になります。
型の限界以上に数字が増えることはありません。
右シフトには符号付き右シフトと符号なし右シフトがあります。

左シフト

移動した後のbitには0が入ります。
byte d = 0x15;
System.out.println("d:"+Integer.toBinaryString(d));
System.out.println("d<<2:"+Integer.toBinaryString(d<<2));
//実行結果
    d:00010101
d<<2:01010100
※結果を解りやすくするために0を追加した8bitの範囲内で表示しています。
int mask = 1;
for (int i=0; i<8; i++) {
  mask = mask << 1; //2,4,8,..となっていく
}

右シフト

符号あり

移動した後の一番左側のbitに、シフトする前にあったbitの数値が入ります。
byte e = -20;
System.out.println(e>>2);
System.out.println("e:"+Integer.toBinaryString(e));
System.out.println("e:"+Integer.toBinaryString(e>>2)); 
//実行結果
-5 // -20/2/2;
e:**101100
e:**111011
※結果を解りやすくするために関係のないbitを排除した範囲内で表示しています。

符号なし

そこまでの値のbitを右にシフトすることに重きを置いたシフト方法です。
移動した後に残ったbitには必ず0が入ります。
byte f = 23;
System.out.println("f:"+Integer.toBinaryString(f));
System.out.println("f:00"+Integer.toBinaryString(f>>>2));
//実行結果
f:10111
f:00101
  • ビット演算
//キー押しながらの操作をするような場面で。
//Shift 押しつつ Ctrl も押したときの処理に名前をつけるような場合。
//Java なら実際には KeyEvent クラスの定数を使うんだろうけど。。。
final int FLAG_SHIFT = 1, FLAG_CTRL = 2, FLAG_ALT = 4;
final int FLAGS_COPY_AND_SLIDE = FLAG_SHIFT | FLAG_CTRL; 
表やサンプルなどは改めてこちら

PHP

ビット演算子

AND,OR,XOR,NOT全てJavaと同一の記号を使います。
  • ANDの実行例
 $x = intval( "1011", 2 );
 $y = intval( "1101", 2 );
 printf( "%04b", ( $x & $y ) ); //1001

シフト演算子

左シフトはJavaと同じですが右シフトには符号なし右シフトがありません。
つまり、空きbitが出たら必ず0で埋めることになります。
 $x = intval( "1011", 2 );
 printf( "%04b", ($x >> 1) ); //0101
 //($x >> $y)としてシフトされるbit数を指定することも可能です。

代入演算子

ビット演算子で計算した後、比較前の変数にそのまま値を入れることが出来ます。
AND,OR,XOR,右シフト,左シフトで使用可能です。
 $x = intval( "1011", 2 );
 $y = intval( "1101", 2 );
 $x &= $y; //$x = $x & $yと同じ。
 printf( "%04b", $x ); //1001

JavaScript

ビット演算子

AND,OR,XOR,NOT全てJavaと同一の記号を使います。
  • ANDの実行例
var num;
num = 0x55 | 0x0F;
document.write("<p>0x55 & 0x0F = " + num.toString(2) + "</p>");
//実行結果 0x55 & 0x0F = 1011111

シフト演算子

ヒアドキュメントとの混同を防ぐためJavaと同じ全てのシフト演算子が使えることになります。
num = 0x15 << 2; //84
document.write(num);
num = 0x2A >> 2; //10
document.write(num);
num = 0xFF00002A >> 2;
document.write(num); //-4194294
num = 0xFF00002A >>> 2;
document.write(num); //1069547530

タグ:

+ タグ編集
  • タグ:

このサイトはreCAPTCHAによって保護されており、Googleの プライバシーポリシー利用規約 が適用されます。

最終更新:2014年01月06日 16:31