5

私は高校生で、現在 Delphi XE3 で学習しています。BIT操作について学習しています。課題があり、この件について多くのことを読み、Bits と SHL/SHR に情報を保存するプロセス全体を理解しましたが、Delphi でこのプロセスを行う方法を理解するのに苦労しています。

割り当ては次のとおりです。

Decimal        Hexidecimal    Binary
1              0x0001         0000000000000001
2              0x0002         0000000000000010
4              0x0004         0000000000000100

オプション セットを識別するために、XML ファイルで整数値を渡します。例えば。オプション 1 とオプション 2 を送信する場合は、1+2=3 を追加します。オプション 1 と 2 が true であることを指定するには、数値として 3 を送信します。

クライアントでは、バイナリ値は 0000000000000011 = 3 になります。

私が読んだことから、マスクを使用する必要がありますが、これを行う方法がわかりません. Delphi でマスクを使用して、True または False になる個々の値を取得するにはどうすればよいですか。

通常の整数変数でこれを実行しようとしましたが、常に整数として扱われ、結果は非常に奇妙です。整数をバイナリ文字列表現に変換し、文字を繰り返し処理すると、結果は正しいですが、文字列でこれを行うべきではないと想定しています。どんな助けや例も大歓迎です。ありがとうございました。

4

3 に答える 3

3

and通常、バイナリ演算子を使用して特定のビットが整数変数に設定されているかどうかを確認し、次のorように演算子を使用して個々のビットを設定します。

const
  OPTION_X = $01;
  OPTION_Y = $02;
  OPTION_Z = $04;

var
  Options: Byte;
begin
  Options := OPTION_X or OPTION_Y;  //actually 3, like in your example
  //check if option_X is set
  if (Options and OPTION_X) = OPTION_X then
    ShowMessage('Option X is set');  //this message is shown, because the bit is set
  //check if option_Z is set
  if (Options and OPTION_Z) = OPTION_Z then
    ShowMessage('Option Z is set');  //this message is NOT shown
end;

さまざまなOPTION_定数は実際には mask であり、ビットを 0 にマスクする (特定のビットが設定されているかどうかを確認する) か、ビットを 1 にマスクする (特定のビットを設定する) ために使用されるという意味で使用されます。

次のフラグメントを検討してください。

begin
  ..

  if cbOptionX.Checked then
    Options := Options or OPTION_X;
  ..

最初のorビットを 1 にマスクします。01010000 のオプション値 (バイナリ) で開始すると、結果のオプションは 01010001 になります。

    01010000   
 OR 00000001  //OPTION_X 
  = 01010001   

同じ値を使用して他のすべてのビットを 0 にマスクし、特定のビットが設定されているかどうかを確認します。if条件 (例: (Options and OPTION_Z) = OPTION_Z) は、次の ことを行います。

  • 最初に、Option 変数の重要でないすべてのバイトを 0 にマスクします。01010001 の最後の値を考慮すると、操作によってすべてのビットがクリアされますが、最初のビットはクリアされます。

        01010001   
    AND 00000001   
      = 00000001   
    

01010000 の開始値を考慮すると、ゼロが返されます。

        01010000   
    AND 00000001   
      = 00000000   
  • 次に、その値がマスク自体と等しいかどうかを比較します。等しい場合、ビットは元の Options 変数に設定されており、それ以外の場合は設定されていません。マスクに 1 ビットしか含まれていない場合は好みの問題ですが、結果の値がたとえば 0 と異なるかどうかを確認できますが、マスクに複数のビットが含まれていて、すべてのビットが設定されているかどうかを確認したい場合は、等しいかどうかを確認する必要があります。
于 2013-01-23T18:49:20.933 に答える
2

Delphi には、集合演算子を使用できる定義済みの型 TIntegerSet があります。optionsそれが整数であると仮定すると、次のようにビット (0 ベース) が設定されているかどうかを確認できます。

option1 := 0 in TIntegerSet(options); { Bit 0 is set? }
option3 := 2 in TIntegerSet(options); { Bit 2 is set? }

オプションの変更は、Include または Exclude を介して行われます。

Include(TIntegerSet(options), 0); { set bit 0 }
Exclude(TIntegerSet(options), 2); { reset bit 2 }

もちろん、役立つ他の集合演算子を使用することもできます。

于 2013-01-23T19:19:27.027 に答える
1

Delphi には、整数型の個々のビットを操作するためのビット演算子があります。、、、、および演算子shlを見てください。ビットを結合するには、演算子を使用します。ビットをテストするには、演算子を使用します。たとえば、次の定数を想定します。shrandorxororand

const
  Option1 = 0x0001;
  Option2 = 0x0002;
  Option3 = 0x0004;

演算子は、両方の入力値のビットを調べて、どちらかの入力値にビットがある場所にビットorがある出力値を生成します。したがって、ビットを組み合わせると次のようになります。11

var
  Value: Integer;
begin
  Value := Option1 or Option2;
  {
  00000000000000000000000000000001 Option1
  00000000000000000000000000000010 Option2
  -------------------------------- OR
  00000000000000000000000000000011 Result
  }
  ...
end;

and演算子は両方の入力値のビットを調べ、両方の入力値にビットがある場所にのみビットがある出力値を生成します。1それ1以外の場合は、0代わりにビットを生成します。したがって、ビットのテストは次のようになります。

var
  Value: Integer;
  Option1Set: Boolean;
  Option2Set: Boolean;
  Option3Set: Boolean;
begin
  Value := 7; // Option1 or Option2 or Option3

  Option1Set := (Value and Option1) = Option1;
  {
  00000000000000000000000000000111 Value
  00000000000000000000000000000001 Option1
  -------------------------------- AND
  00000000000000000000000000000001 Result
  }

  Option2Set := (Value and Option2) = Option2;
  {
  00000000000000000000000000000111 Value
  00000000000000000000000000000010 Option2
  -------------------------------- AND
  00000000000000000000000000000010 Result
  }

  Option3Set := (Value and Option3) = Option3;
  {
  00000000000000000000000000000111 Value
  00000000000000000000000000000100 Option3
  -------------------------------- AND
  00000000000000000000000000000100 Result
  }
  ...
end;
于 2013-01-23T18:56:33.367 に答える