3

このタスクを実行するコードをオンラインで見つけました。

byte = byte >> field;
byte = byte & 0x01;
return(byte);

ただし、これができない理由がわかりません。

return(byte & field);

これは機能しますか?なぜですか、そうでないのですか?より良い実装はありますか?

4

6 に答える 6

3

最初のものは次のものと同等です:

return (byte >> field) & 0x01;

それが実際に行うことは、位置のあるビットにシフトし、そのビットが設定されている場合はfield戻り、そうでない場合は戻ります。10

提案したものは、指定されたフィールドのオフセットにシフトしないため、正しくありません。たとえば、byte & 5意味がありません。

関数は次のように書くこともできます:

return byte & (1 << field);

もちろん、1 << 5の代わりに渡すつもりなら5、あなたはそれをあなたのやり方で書くことができます。

field関心のあるビットの位置を示す数値だと思います。したがって、1バイトの場合は範囲​​内になります0..7

于 2011-06-09T15:39:29.617 に答える
1

最初のコードサンプルでは、​​fieldは、値が必要なフィールド内のビットの位置です。

2番目のサンプルでは、​​フィールドはそのビットが1に設定されたintである必要があります1 << field

于 2011-06-09T15:38:35.997 に答える
1

バイトを右にシフト

field右側からのワードのビット数(LSB)を表します。バイトbyte = byte >> fieldのビット番号をLSB位置に持ってきます。次に、そのバイトは、元々ビット番号にビットが設定されていた場合はLSBにaが含まれ、その位置でビットがクリアされた場合は結果にaが含まれることを意味します。fieldbytebyte = byte & 0x010x011field0

たとえば、バイト0x52にビット番号4が設定されているかどうかを確認するために必要なテストを以下に示します。

    byte   = 0x52 =  0 1 0 1 0 0 1 0

    field  = 0x04 =  0 0 0 0 0 1 0 0

    Operation: byte = byte >> field

    The bit number 4 is single quoted below. Note how it moves

                                  intermediate byte       | lost bits during
                                        states            | right shifting

    byte         = 0x52         = 0  1  0 '1' 0  0  1  0  |
    shift 1      = 0x29         = 0  0  1  0 '1' 0  0  1  | 0
    shift 2      = 0x14         = 0  0  0  1  0 '1' 0  0  | 1 0
    shift 3      = 0x0A         = 0  0  0  0  1  0 '1' 0  | 0 1 0
    shift 4      = 0x05         = 0  0  0  0  0  1  0 '1' | 0 0 1 0

    Note that the bit 4 is now moved at the LSB/righ most position of the byte
    now if we test the rightmost position of the above byte then we can check
    if the bit number 4 had its bit set or cleared, with the following operation

    Operation: byte = byte & 0x01

    byte is now 0x05

    byte         = 0x05  = 0 0 0 0 0 1 0 '1'
    AND                    & & & & & & &  &
                   0x01  = 0 0 0 0 0 0 0  1
                   ----    ----------------
                   0x01    0 0 0 0 0 0 0  1

   Now byte contains 0x01 so bit number 4 had the bit set. In the other case the
   final answer would be 0.

ただし、番号が付けられているビットが設定またはクリアされているかどうかを確認することはできません。これは、が単なるバイナリであり、マスクではないためです。そうすると、次のことが起こります。byte & fieldfieldfieldbyte & field

  byte         = 0x52  = 0 1 0 1 0 0 1 0
  AND                    & & & & & & & &
  field        = 0x04  = 0 0 0 0 0 1 0 0
                 ----    ---------------
                 0x00    0 0 0 0 0 0 0 0

field0x04は、ビット番号2が設定されています。この操作で、ビット番号2が設定されているかどうかを実際に確認しました。の値がfieldビット50あり、が設定される場合、ビットの状態との値を2抽出すると、上記のように直接ANDを実行すると、4つの可能な組み合わせが可能になります。02byte

0x01を左にシフトし、マスクを作成します

aのビット値をテストする他の方法は、それ自体をシフトbyteする代わりに、マスク時間を左にシフトし、それをバイトとANDして、ゼロかどうかを確認することです。番号付きビットが設定されている場合はtrue、それ以外の場合はfalseになります。byte0x01field(byte & (0x01 << field)) != 0field

   Operation: (0x01 << field)

      Shifting 0x01 to the left field times field = 0x04 for the example

                 = 0x01             = 0 0 0 0 0 0 0 1  
    shift 1      = 0x02             = 0 0 0 0 0 0 1 0
    shift 2      = 0x04             = 0 0 0 0 0 1 0 0
    shift 3      = 0x08             = 0 0 0 0 1 0 0 0
    shift 4      = 0x10             = 0 0 0 1 0 0 0 0


      After the left shift the '1' moves in the bit position 4
      Now we AND this with the byte to check if the bit position 4
      is set or clear.

  byte            = 0x52  = 0 1 0 1 0 0 1 0
  AND                       & & & & & & & &
  (0x01 << field) = 0x10  = 0 0 0 1 0 0 0 0
                    ----    ---------------
                    0x10    0 0 0 1 0 0 0 0

  Therefore the answer (0x01 != 0) is 1 there fore the bit 4 is set. It the bit 4
  was not set then the answer would be 0.

事前に計算されたマスクを使用する

定期的にテストする必要がある特定の形式のバイトがある場合、たとえば、各ビットが特定のことを意味する事前定義された単語のビットフィールドがある場合は、特定のビット位置にのみ1つあるプリコンピューターマスクを保持できます。そのマスクでテストされます。たとえば、1バイトをチェックするには、プリコンピュータマスクは次のようになります。

#define BIT_0 0x01 //(00000001)
#define BIT_1 0x02 //(00000010)
#define BIT_2 0x04 //(00000100)
#define BIT_3 0x08 //(00001000)
#define BIT_4 0x10 //(00010000)
#define BIT_5 0x20 //(00100000)
#define BIT_6 0x40 //(01000000)
#define BIT_7 0x80 //(10000000)

したがって、ビット4をテストするには、次のbyteことを行うreturn (byte & BIT_4)必要があります。return (byte & BIT_4) != 0;

ビット位置が何を表すかに応じて、マクロの名前を設定できます。

于 2011-06-10T03:37:07.003 に答える
1

戻り値をゼロまたは1にしたい場合は、次のいずれかを実行できます

return ((byte & (1 << field)) != 0);

また

return ((byte >> field) & 0x01);

どちらの形式も、戻り値がゼロか非ゼロかだけを気にする場合、少し単純化されます。

于 2011-06-09T15:46:48.237 に答える
0

1 番目の例では、必要なビットを戻り値の LSB に移動しますが、2 番目の例では、不要なすべてのビットを単純にマスクします。

于 2011-06-09T15:50:27.473 に答える