web-dev-qa-db-ja.com

ビットマスクの質問?

私は以下を持っています:

public static final int LIMIT_ONE = 1;
public static final int TRADEABLE = (1 << 1);
public static final int SELLABLE = (1 << 2);
public static final int STORABLE = (1 << 3);
public static final int STORABLE_IN_WH = (1 << 4);
public static final int STORABLE_IN_LEGION_WH = (1 << 5);
public static final int BREAKABLE = (1 << 6);
public static final int SOUL_BOUND = (1 << 7);
public static final int UNK9 = (1 << 8);
public static final int UNK10 = (1 << 9);
public static final int UNK11 = (1 << 10);
public static final int CAN_COMPOSITE_WEAPON = (1 << 11);
public static final int BLACK_CLOUD_TRADERS = (1 << 12);
public static final int CAN_SPLIT = (1 << 13);
public static final int UNK15 = (1 << 14);
public static final int UNK16 = (1 << 15);

そして、次の結果が得られるように計算される方法を理解したかったのです。たとえば、12414

私はビットマスクがどのように機能するかについて本当に無知です、そして誰かがおそらくいくつかのヒントを与えて、それがその数にどうなるかを説明することができれば私は非常に感謝します。

23
Prix

(1 << n)は、2のn乗に相当します。

(1 << n) | (1 << m)と書く場合、nmが異なる限り、これは(1 << n) + (1 << m)と同じです。したがって、必要に応じて、単純な追加の観点から考えることができます。

2進数の12414の数は11000001111110であるため、次のフラグの合計(またはビットごとのOR)になります。

 TRADEABLE 1 << 1 = 2 
 SELLABLE 1 << 2 = 4 
 STORABLE 1 << 3 = 8 
 STORABLE_IN_WH 1 << 4 = 16 
 STORABLE_IN_LEGION_WH 1 << 5 = 32 
 BREAKABLE 1 << 6 = 64 
 BLACK_CLOUD_TRADERS 1 << 12 = 4096 
 CAN_SPLIT 1 << 13 = 8192 
 ======================================== 
合計= 12441 

含まれているフラグは、右から左に読み取るときに12414のバイナリ表現で設定されているビットに対応していることに注意してください。

20
Mark Byers

binary の12414は次のとおりです。

_Binary number: 1  1  0  0  0  0  0  1  1  1  1  1  1  0
-------------------------------------------------------
Bit positions: 13 12 11 10 9  8  7  6  5  4  3  2  1  0
_

どのビットが1であるかを確認します。これらは、ビットごとのOR演算子を使用してフラグを結合することによって作成される、ビットマスクに設定されるフラグです。

_bitmask = TRADEABLE | SELLABLE | STORABLE | STORABLE_IN_WH | STORABLE_IN_LEGION_WH | BREAKABLE | BLACK_CLOUD_TRADERS | CAN_SPLIT;
_

これをさらに説明するために、STORABLE = (1 << 3);は、STORABLEが左に3桁シフトされた数値1(バイナリ1、ビット位置0にのみ該当)に等しいことを意味します。 STORABLE = Math.pow(2, 3);は同等であることに注意してください。フラグ間で重複するビットはないため、すべてのビットを1つのintに結合し、後で分割することができます。

ビット単位のAND演算子を使用してフラグの存在を確認できます。この演算子は、フラグが設定されている場合はゼロ以外の値を返し、フラグが設定されていない場合はゼロ値を返します。

_if(bitmask & TRADEABLE != 0) {
    // This item can be traded
} else {
    // This item cannot be traded
}
_

次のようにフラグを設定、クリア、または切り替えることができます。

_bitmask |= TRADEABLE; // Sets the flag using bitwise OR
bitmask &= ~TRADEABLE; // Clears the flag using bitwise AND and NOT
bitmask ^= TRADEABLE; // Toggles the flag using bitwise XOR 
_
37
PleaseStand

a << bは、ab値のビットを左にシフトし、右側の新しいビットにゼロを埋め込みます。 1 << nは、n番目のビット(右から0から数えて)のみが設定された整数に相当します。これは2に相当します。n

12414は、バイナリでは11000001111110です。したがって、以下にリストされている定数を合計することによって生成されます。これは、右からのビット1が設定されていることを確認することで解決できます。したがって、TRADEABLEは「設定」されています。ビット7は設定されていない(0)ため、SOUL_BOUNDは「設定」されていません。ビット番号が(1 << n)の宣言された値とどのように関連付けられているかに注意してください。

TRADEABLE
SELLABLE
STORABLE
STORABLE_IN_WH
STORABLE_IN_LEGION_WH
BREAKABLE
BLACK_CLOUD_TRADERS
CAN_SPLIT
5
moinudin

「次の結果が得られるように計算する方法」という質問がわかりません。 (何が計算されますか?)

理解すべき主なことは、すべてのコンピューター値がバイナリーで保管されるということです。任意の数は0ビットと1ビットの組み合わせになります。一部の数値には1ビットしかありません。

http://en.wikipedia.org/wiki/Mask_(computing

0
Jonathan Wood

私の推測では、例12414などの数値を取得して、その中に含まれているプロパティを把握していると思います。

たとえば、12414はバイナリで11000001111110であるため、この数値をマスクとAND演算すると、2番目のビットに1が与えられるため、アタッチされているものはすべてトレード可能です。

0
Erix

バイナリでは、12414は11000001111110です。バイナリのLIMIT_ONEは1で、ビットシフト演算子である<<は、ゼロを左のパディングに移動し、右にゼロを配置します。したがって、バイナリでトレード可能なのは10などで、unk16までは1000000000000000になります。ここで、ビット単位のORを使用してこれらの値をまとめます。これにより、基本的に、オペランドの少なくとも1つがその位置に1を持つ各位置に1が配置されます。 (パイプ演算子 '|'はほとんどの言語で使用されます)。

例:

100 | 10 = 110

したがって、12414に到達するには、次の変数に対してビット単位のORを実行する必要があります:unk16、unk15、tradeable、selleable、storeable、storeable in wh、storeable in legion wh、breakable。これらの各変数の異なる位置にあるものを組み合わせると、バイナリ11000001111110が得られ、10進数で12414になります。

これはおそらくそれを説明する最も簡単な方法です。詳細を知りたい場合は、ビット演算子と数値の2進表現がどのように機能するかを確認する必要があります。

数値12414のフラグを確認するには、&(ビット単位のAND)演算子を使用して、ゼロチェックを実行します。例えば:

6 & 2 = 2 (110 has a 1 on the same position as 2, which is 010)
6 & 1 = 0 (110 does not have a 1 on the same position as 1, which is 001)
0
VoY