ホームページ  >  記事  >  Java  >  Java のビット操作とアプリケーション シナリオの概要

Java のビット操作とアプリケーション シナリオの概要

王林
王林転載
2021-03-08 16:32:384484ブラウズ

Java のビット操作とアプリケーション シナリオの概要

プログラム内のすべての数値はコンピューター メモリにバイナリ形式で格納されており、ビット操作はメモリ内の整数のバイナリ ビットを直接操作することを知っています。たとえば、and 演算は本来論理演算子ですが、整数同士でも AND 演算を行うことができます。

ビット演算には主にシフト演算と論理演算があります。次に、シフト演算と論理演算についてそれぞれ説明します。

シフト演算:

左シフト: 演算子は 670fcc7a1befaf9094faa244b91a4c62>> で、右に移動し、右側を破棄し、左側に 0 を追加します。符号付き右シフト: 演算子は >> で、右に移動し、右側を破棄します。左側に追加される値は、元の最上位ビットによって決まります。元が 1 の場合は 1 を追加し、0 の場合は 1 を追加します。 、0 を追加します。バイナリを次のように考えてください。整数の場合、それを 1 ビット右にシフトすることは、2 で除算することと同じです。

例:

int a = 4; // 100
a = a >> 2; // 001,等于1
a = a << 3 // 1000,变为8

論理演算には次のものが含まれます:

  • ビットごとの AND&: 両方のビットが 1 から 1 になる

  • ビットごとの OR|: 1 つのビットが 1 である限り、1 です

  • ##ビットごとの否定~: 1 は 0 になり、0 は 1 になります

  • bitwise アプリケーション シナリオ:

    シナリオ 1: パリティの決定
分析: 奇数は 2 の整数倍ではありません。バイナリに変換した後、最下位ビットは 1 でなければならず、その逆はは偶数の場合に当てはまります。この機能を使用すると、ビット操作を通じて整数のパリティを簡単に決定できます。

コードを見てください:

int a = ...; 
a = a & 0x1 // 返回0或1,就是a最右边一位的值。
a = a | 0x1 //不管a原来最右边一位是什么,都将设为1

シナリオ 2: 正の整数が 2 の整数乗であるかどうかを判断します。

分析: まず、一般的な 2 の整数乗を見てみましょう。数字: 2、4、8、16 を 2 進数に変換すると、10、100、1000、10000 になります。パターンは見つかりましたか?つまり、1 である最初のビットを除いて、他のビットはすべて 0 です。これらの数値から 1 を引いた後、ビットごとの反転の結果が等しくなるのは偶然です。たとえば、8-1=7 (2 進数で 111) は、8 の 2 進数 1000 をビットごとに反転することで得られます。そして 8&7=0 の場合、ルールを抽出すると次のようになります。

   int i = 1;// 二进制存储方式为00000000000000000000000000000001
    int j = 5;// 二进制存储方式为00000000000000000000000000000101
    int k = 6;// 二进制存储方式为00000000000000000000000000000110
    if ((i & j) == 1) {
      System.out.println("j的最低位为1,为奇数");
    }    if ((i & k) == 0) {
      System.out.println("k的最低位为0,为偶数");
    }

このルールに適合する n は 2 の整数乗です。

(学習ビデオ共有:

java ビデオ チュートリアル

)

シナリオ 3: 単純なコレクション処理

ナンセンスではありません。コードを見てください:

(n&(n-1))==0
テストします:
public class SimpleSet {  public static final int A = 0x01;// 最后四位为0001
  public static final int B = 0x02;// 最后四位为0010
  public static final int C = 0x04;// 最后四位为0100
  public static final int D = 0x08;// 最后四位为1000
  private int set = 0x00;// 初始0000,空集合
  public void add(int i) {// 将i对应位的值置为1,重复add不影响。默认传入值为ABCD之一,此处省去边界判断
    set |= i;
  }  public boolean contain(int i) {// 判断相应位置是否为1
    return (set & i) == i;
  }  public boolean remove(int i) {// 来不及不解释了快看代码
    if (contain(i)) {
      set -= i;      return true;
    } else {      return false;
    }
  }
}

出力は次のとおりです:

 public static void main(String[] args) {
    SimpleSet set = new SimpleSet();
    System.out.println(set.contain(A));
    set.add(B);
    System.out.println(set.contain(A));
    System.out.println(set.contain(B));
    set.add(A);
    set.add(C);
    System.out.println(set.contain(A));
    set.remove(A);
    System.out.println(set.contain(A));
    System.out.println(set.remove(A));
    System.out.println(set.contain(C));
  }

わかりました、問題ありません。

上記のコード例の A、B、C、D は列挙型に似ていると思われるかもしれません。実際、列挙型の jdk ソース コードにあるコレクション クラス EnumSet は同様のソリューションを使用しています。これよりもはるかに複雑です。興味がある場合は、ソース コードを確認してください。このソリューションには、ビット ベクトルと呼ばれる名前が付いています。

ちなみに、Java の int のパッケージングクラスである Integer にはビット演算を提供する静的ツールが多数あり、非常に複雑なものが多いので、興味のある方は覗いてみてください。

結論:

ビット演算はコンピュータが最も得意とする演算であり、jdkのソースコードにも多用されており、これを理解することでコンピュータをより深く理解することができ、また、よりエレガントなコードを書くのにも役立ちます。

関連する推奨事項:

Java 入門チュートリアル

以上がJava のビット操作とアプリケーション シナリオの概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はcnblogs.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。