13


13

アプリケーションフレームワークでは、私はあなたが関数に複数のInt値(通常はenumの代わりに使用される)を渡すことを可能にするフレームワークを見続けています。

例えば:

パブリッククラス例{パブリッククラス値{public static final int ONE = 0x7f020000; public static final int TWO = 0x7f020001; public static final int THREE = 0x7f020002; public static final int FOUR = 0x7f020003; public static final int FIVE = 0x7f020004; }

public static void main(String [] args){// Values.ONEだけを評価するべきです。Example.multiValueExample(Values.ONE);

// Values.ONE、Values.THREE、Values.FIVEの値だけを評価する必要があるExample.multiValueExample(Values.ONE | Values.THREE | Values.FIVE);

//値のみを評価するべきValues.TWO、Values.FIVE Example.multiValueExample(Values.TWO | Values.FIVE); }

public static void multiValueExample(int values){//ビットごとの値を正しく評価するロジック... }}

では、ビット演算子を使用して渡される複数のint値を正しく評価するためには、multiValueExampleにどのようなロジックが存在すればよいのでしょうか。

8 Answer


31


あなたの価値は2のべき乗であるべきです。

そうすれば、ビットごとの論理和をとっても情報が失われることはありません。

public static final int ONE = 0x01; public static final int TWO = 0x02; public static final int THREE = 0x04;パブリックスタティックfinal int FOUR = 0x08。 public static final int FIVE = 0x10。

それからこれをすることができます:

public static void main(String [] args){Example.multiValueExample(Values.ONE | Values.THREE | Values.FIVE);} }

public static void multiValueExample(int values){if((values)

if((値

//など }


9


すでに述べたように、ビット値の代わりに列挙型の使用を検討してください。

https://rads.stackoverflow.com/amzn/click / com / 0321356683 [Effective Java 2]によると、_ "Item 32: EnumSet

http://java.sun.com/j2se/1.5.0/docs/api/java/util/EnumSet.html[EnumSet]を使用すると、メモリ使用量に対して非常に効果的で非常に便利です。

これが一例です。

パッケージ列挙

java.util.EnumSetをインポートします。 import java.util.Set;

パブリッククラスの例{public enum値{1、2、3、4、5}

public static void main(String [] args){// Values.ONEだけを評価する必要があります。Example.multiValueExample(EnumSet.of(Values.ONE));

//値Values.ONE、Values.THREE、Values.FIVEだけを評価する必要があります。Example.multiValueExample(EnumSet.of(Values.ONE、Values.THREE、Values.FIVE));

// Values.TWO、Values.FIVEだけを評価するべきであるExample.multiValueExample(EnumSet.of(Values.TWO、Values.FIVE)); }

public static void multiValueExample(値を設定){if(values.contains(Values.ONE)){System.out.println( "One"); }

//その他の確認事項はこちら

if(values.contains(Values.FIVE)){System.out.println( "Five"); }}}


5


各列挙値がバイナリ表現の1ビットになるように、2の累乗になるように整数値を設定します。

int ONE = 0x1。 // 0001 int TWO = 0x2; // 0010 int THREE = 0x4; // 0100 int FOUR = 0x8。 // 1000

次に、ビットごとのORを使用して値を結合し、ビットごとのANDを使用して設定値をテストします。

int test_value =(ONE | FOUR); //  - > 1001 bool has_one =(test_value


4


|と組み合わせる値(論理和ではなく、2進論理和[これは||]である)は、それらのビット表現に重複する "1"があってはならない。 例えば、

1 = 0x1 = 0000 0001 2 = 0x2 = 0000 0010 3 = 0x3 = 0000 0011 4 = 0x4 = 0000 0100

次に、ONEとTWOを組み合わせることができます。例えば:

ONE | TWO = 0000 0011

しかし、あなたは一つを区別することはできません。重複するビットがあるため、THREEから2つ。 したがって、組み合わせる数は2の累乗である必要があります。これは、ORで結合したときに重ならないようにするためです。 数値が "values"で渡されたかどうかをテストするには、次のようにします。

if(値 その後1が設定されました}

なぜそしてどのようにこれが機能するのかをよりよく理解するために、私はあなたがバイナリ表現とロジックについて少し読むことをお勧めします。 良い場所は アセンブリオブアートの第3章です。


3


まず、値をビットごとに比較するように定義することはできません。 代わりに、異なるビットを設定してください。

public static final int 1 = 0x1。 //最初のビットはpublic static final int TWO = 0x2に設定されています。 // 2番目のビットはpublic static final int THREE = 0x4に設定されています。 // 3番目のビットはpublic static final intに設定されていますFOUR = 0x8; // 4番目のビットはpublic static final int FIVE = 0x10に設定されています。 // 5番目のビットが設定されている

次に、これらの種類の操作には、おそらく* http://java.sun.com/javase/6/docs/api/java/util/BitSet.html [java.util.BitSet] *を使用する必要があります。

ビットセットビット=新しいビットセット(5)。 bits.set(2); bits.set(4);

System.out.println( "これらのビットが設定されています:"ビット);
// Prints "these bits are set: {2, 4}"

BitSet otherBits = new BitSet(5); otherBits.set(3)。 otherBits.set(4)。

System.out.println( "これらのビットが設定されています:" bits.or(otherBits));
// Prints "these bits are set: {2, 3, 4}"


3


2のべき乗であれば、以下のコードの "display"メソッドのようなことをするでしょう。

http://en.wikipedia.org/wiki/Mask_%28computing%29[このトピックについてのウィキペディアのリンクもあります]これはなぜ2のべき乗が欲しいのか説明するはずです。
パブリッククラスMain {private static final int A = 0x01;プライベートスタティックfinal int B = 0x02。プライベートスタティックfinal int C = 0x04。

public static void main(final String [] argv){display(A);ディスプレイ(B)。ディスプレイ(C)。表示(A | A)表示(A | B)表示(A | C)表示(B | A)表示(B | B)表示(B | C)表示(C | A)表示(C | B)表示(C | C)。表示(A | A | A);表示(A | A | B);表示(A | A | C);表示(A | B | A);表示(A | B | B);表示(A | B | C);表示(A | C | A);表示(A | C | B);表示(A | C | C);表示(B | A | A);表示(B | A | B);表示(B | A | C);表示(B | B | A);表示(B | B | B);表示(B | B | C);表示(B | C | A);表示(B | C | B);表示(B | C | C);表示(C | A | A);表示(C | A | B);表示(C | A | C);表示(C | B | A);表示(C | B | B);表示(C | B | C);ディスプレイ(C | C | A);表示(C | C | B);表示(C | C | C); }

プライベート静的無効表示(final int val){if((val

if((val

if((val

System.out.println(); }}


3


すべてのビットがカウントされるときにビットマスクを使用するのが一般的でした。 今日これを行う別の方法は、enumを使って、操作と拡張がより簡単になることです。

Import static Example.Values。*; import java.util.Arrays;

パブリッククラスの例{public enum値{1、2、3、4、5}

public static void main(String [] args){// Values.ONEを評価するだけです。multiValueExample(1);

// Values.ONE、Values.THREE、Values.FIVEの値だけを評価します。multiValueExample(ONE、THREE、FIVE);

// Values.TWO、Values.FIVEだけを評価します。multiValueExample(TWO、FIVE); }

public static void multiValueExample(値... values){// System.out.println(Arrays.asList(values))を正しく評価するロジック。 for(Values value:values){//何かをします。 }}}


0


ビット単位操作に関するJavaチュートリアルの章は、

とても簡潔ですが、参考にしてください。