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。我会发送 3 作为数字来指定选项 1 和 2 为真。

在客户端,二进制值为 0000000000000011 = 3

根据我的阅读,我需要使用面具,但我不明白如何做到这一点。我将如何在 Delphi 中使用掩码来获取 True 或 False 的各个值。

我尝试在常规 Integer 变量中执行此操作,但它总是被视为 Integer,结果非常奇怪。如果我将整数转换为二进制字符串表示并遍历字符,则结果是正确的,但我假设我不应该对字符串执行此操作。任何帮助或示例将不胜感激。谢谢你。

4

3 回答 3

3

and您通常使用二元运算符检查是否在 Integer 变量中设置了特定位,然后使用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_常量实际上是掩码,从某种意义上说,它们用于将位掩码为零(以检查是否设置了特定位)或将​​位掩码为 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 变量中设置该位,否则不设置。如果您的掩码仅包含一位,那是口味问题,您可以检查结果值是否不同于 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(TIntegerSet(options), 0); { set bit 0 }
Exclude(TIntegerSet(options), 2); { reset bit 2 }

当然,您可以使用任何其他可能有用的集合运算符。

于 2013-01-23T19:19:27.027 回答
1

Delphi 具有用于操作整数类型的各个位的位运算符。查看shl, shr, and, or, 和xor运算符。要组合位,请使用or运算符。要测试位,请使用and运算符。例如,假设这些常量:

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

or运算符查看两个输入值的位,并产生一个输出值,该输出值在1任一输入值都有位的地方有一个1位。所以组合位看起来像这样:

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 回答