ビット操作ノート(Java)

4284 ワード

ビット操作演算の概要
 
取反(NOT)
逆は1元演算子で、1つのバイナリ数の各ビットに対して論理を実行します
に逆らうで動作します.数字1を0、0を1にします.例:
NOT 0111(10進7)=1000(10進8)
Javaでは、リバースオペレータを波線「~」で表します.このオペレータは、論理非(!)オペレータとは異なり、論理非はビット操作ではありません.
 
ビットまたは(OR)
2つの長さが同じ2進数をビットまたは処理し、2つの対応する2進数のうち1つが1であれば、そのビットの結果値は1である.たとえば
0101(10進5)OR 0011(10進3)=0111(10進7)
JAvaでは、ビット単位またはオペレータは「|」
一人一人を旗と見なすことができる.バイナリ数の各ビットは、異なるブール変数を表すことができる.ビット単位または操作を適用すると、バイナリ数のいずれかを1に設定できます.たとえば
0010(10進数2)
4つの旗を含む組み合わせと見ることができます.第1、2、4の旗は0です.3番目の旗は1です.1番目のフラグを1に設定するか、他のフラグは変更されません.
0010(10進2)OR 1000(10進8)=1010(10進10)
このテクニックは、通常、プログラム内の大量のブール変数を保存するために使用されます.
 
ビット別OR(XOR)
ビット別または演算により、等長バイナリモードに対してビットまたはバイナリ数の各ビット毎に論理ビット別または操作が実行され、その結果、あるビットが異なる場合、そのビットは1であり、そうでない場合、そのビットは0であり、例えば
0101 XOR 0011 = 0110
JAvaでは、ビット単位またはオペレータは「^」
アセンブリ言語のプログラマーたちは、レジスタの値を0にする近道としてビット別または演算を使用することがある.値自体でビット別または演算を行うと0になります.また、多くのアーキテクチャでは、0値を直接ロードしてレジスタに保存するよりも、ビット別または演算には中央処理ユニットクロック周期が少ない.
ビット別またはビットセットでフラグを交換するために使用することもできる.ビットモードが与えられ、
0010
第1及び第3のビットは、ビット別又は演算により同時に切り換えることができる.
0010 XOR 1010 = 1000
この技法は、ブール変数を表すビットパターンを操作するために用いることができる.
 
ビットアンド(AND)
ビットと処理の2つの長さの同じバイナリ数で、2つの対応するバイナリビットはすべて1で、そのビットの結果値は1で、そうでなければ0です.例:
0101 AND 0011 = 0001
Javaでは、ビットと'&'で表されます.
 
へんい
シフトは、1つのバイナリ数の各ビットをすべて1つの方向に移動するための2元演算子で、オーバーフローした部分は捨てられ、空き部分は一定の値に埋め込まれます.Javaでは、左シフトは2つの小さい記号「<<」で表され、右シフトは2つの大きい記号「>」で表されます.">>右シフト、高位補記号ビット"ここで右シフトは2">>>"を除いて記号なし右シフト、高位補0"を表す.>>と似ています.
論理シフトを適用する場合、シフト後の空き部分は全て0とする.
0001(10進1)<<3(左へ3桁)=1000(10進8)1010(10進10)>>2(右へ2桁)=0010(10進2)
 
Longとbyte[]が互いに変換される例を示します.
 
package org.oham.testbyte;

public class TestByte {

	
	// Long           
	private byte[] _transLongToByte(long num)
	{
		byte[]b = new byte[4];//     4           Long  
		
		/* 
		 * 1  8 ,      ,     0
		 *      24 , b[0] = 00000000
		 *      16 , b[1] = 00000011
		 *      8  , b[2] = 00001000
		 *      0 , b[3] = 00110010
		 */
		for( int i=0; i< b.length; i++ )
		{
			b[i] = (byte)(num >>> (24 - i*8));
		}
		
		return b;
	}
	
	/*
	 *     :        ,        
	 *        8 ,        ,    
	 *           ,    8 ,    。。。
	 * 
	 *      : 00000000  |   (00000000 & 11111111)   -->   00000000
	 *      : 0000000000000000  |   (00000011 & 11111111)   -->   0000000000000011
	 *      : 000000000000001100000000  |   (00001000 & 11111111)   -->   000000000000001100001000
	 *      : 00000000000000110000100000000000  |   (00110010 & 11111111)   -->   0000000000000011000010000000000000110010
	 * 
	 *       0, :11000010000000000000110010    198706
	 * 
	 */
	private Long _transByteToLong(byte[] b)
	{
		int mark = 0xFF;  //    :11111111
		int tmp = 0;   //              
		long res = 0;  
		
		for( int i=0; i< 4; i++ )
		{
			res = res << 8; //   8 
			
			tmp = b[i] & mark; //  11111111       ,       ,        8      
			
			//        ,        ,  res   0,         ,  8  
			//  8    0,   tmp        res  tmp
			res |= tmp;  
			
			
			System.out.println(res + "----==------" + Long.toBinaryString(res));
		}
		
		return res;
	}
	
	
	public void testByte()
	{
		long num = 198706;  //110000100000110010,       
		byte[] b = this._transLongToByte(num);
		
		long res = this._transByteToLong(b);
		
		System.out.println(res);
	}
	
	public static void main(String[] args) 
	{
		TestByte test = new TestByte();
		
		test.testByte();
	}
}

 この例はただ模範で、ビットの操作は柔軟で、技巧性はとても強くて、正則のタイプと、しばらく精通するのは難しいで、http://bbs.csdn.net/topics/70288919を添付して、暇があればまた総括します.