「(int)値&0x1、(int)値&0x2、(int)値&0x4、(int)値&0x8」はどういう意味ですか? "


11

コード

「値」の範囲は0〜15です(可能な値)。これらの4つの「if」条件はいつ満たされますか?(int)value = 2の場合、これは0010を意味しますか?

            if  ((int)value & 0x1) 
            {
                //statement here
            }
            if  ((int)value & 0x2) 
            {
                //statement here
            }
            if  ((int)value & 0x4) 
            {
                //statement here
            }
            if  ((int)value & 0x8) 
            {
                //statement here
            }

3
これらは(「セットの3番目のビット(= 1)です」と読みます)の個々のビットをチェックするビットマスクです。コードを理解する上で問題があるように思われるので、それはあなたのものではないと思います。これ(そして、レビューのために)オフトピックのため、この質問をするCR.SEvalueif(value & 0x4)value
誰も

よりよく理解するために、C#に移植された同様のコードは、Enum.HasFlagメソッドを使用してビットをテストします。参照:Enum.HasFlag
rwong 14

回答:


12

各数値はvalue = b0*2^0 + b1*2^1 + b2*2^2 + b3*2^3 + ...、各bが0またはであるように表現できます1(これらは表現のビットです)。これはバイナリ表現です。

バイナリAND(&)は、これらの各bペアを適切に処理し、それらに対してANDを実行します。これには次の出力があります。

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

2の累乗(1ビットのみがオン)を使用して、個々のビットを分離してテストできます。

  • value & 1value奇数の場合にtrueになります{1、3、5、7、9、11、13、15}。

  • value & 2value/2奇数の場合にtrueになります{2、3、6、7、10、11、14、15}。

  • value & 4value/4奇数の場合はtrue {4、5、6、7、12、13、14、15}です。

  • value & 8value/8奇数の場合はtrue です{8、9、10、11、12、13、14、15}。

数値の0x接頭辞は、16進数として解釈されることを意味します。0x8までしか上がらない場合は少し不必要ですが、おそらくビットマスクとして使用されているとメンテナに伝えます。


1
:文言は、それが真実ではないすべての数字に拡張することができることを示唆して8/6いる間、奇数の8&6利回りはfalse。
Sjoerd 14

@Sjoerdだから私は「2の累乗」と言った
ラチェットフリーク

5

これらのifステートメントvalueは、特定のビットが設定されているかどうかをチェックします。

0x4たとえば、16進値では、右から3番目のビットがに設定され1、他のすべてのビットはに設定され0ます。&2つの演算子で2項演算子()を使用すると0、両方の演算子で1であるビットを除くすべてのビットが結果に設定されます。

だから、あなたが計算を行うときvalue & 0x4、あなたはどちらかのgetバイナリ00000000またはバイナリ00000100、の3番目のビットがいるか否かに応じて、valueあります10。最初はに評価されfalse、2番目はに評価されるtrueため、if-blockは3番目のビットが設定されている値に対してのみ実行されます。


1

ここで注目すべき2つの興味深い点があります。

まず、これは、整数値の下位4ビットのそれぞれをチェックするための一般的なパターンです。対応するビットが設定されている場合、if条件が満たされます。値2の場合、ビットパターンは確かに0010です。

他のより興味深い質問は、なぜ(int)キャストなのか?C ++でCキャストを使用するという悪いスタイルは別として、このキャストを必要とする整数値や文字値はありません。boolは意味がありません。double/ floatは一時的な整数に変換され、リテラル値を使用してenumをテストすることは珍しいでしょう。ポインタを使用することは理にかなっているかもしれませんが、それは非常に特殊な使用法です。結論:キャストは意味をなしません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.