XML位操作Delphi

XML位操作Delphi,delphi,delphi-xe2,bit-manipulation,Delphi,Delphi Xe2,Bit Manipulation,我是一名高中生,目前在德尔福XE3学习。我们正在学习位操作。我们有一个作业,虽然我读了很多关于这个主题的书,并且理解了以Bits和SHL/SHR存储信息的整个过程,但我很难理解如何在Delphi中完成这个过程 任务如下: Decimal Hexidecimal Binary 1 0x0001 0000000000000001 2 0x0002 0000000000000010 4

我是一名高中生,目前在德尔福XE3学习。我们正在学习位操作。我们有一个作业,虽然我读了很多关于这个主题的书,并且理解了以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为真

在客户端上,二进制值为00000000000000 11=3

从我所读到的,我需要使用一个面具,但我不知道如何做到这一点。如何在Delphi中使用掩码来获取单个值,这些值可能是真的,也可能是假的


我试着在一个正则整数变量中这样做,但它总是被当作一个整数处理,结果非常奇怪。如果我将整数转换为二进制字符串表示形式,并对字符进行迭代,结果是正确的,但我假设我不应该对字符串执行此操作。任何帮助或榜样都将不胜感激。谢谢。

您通常使用
二进制运算符检查整数变量中是否设置了特定位,并使用
运算符设置单个位,如下所示:

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;
var
  Value: Integer;
begin
  Value := Option1 or Option2;
  {
  00000000000000000000000000000001 Option1
  00000000000000000000000000000010 Option2
  -------------------------------- OR
  00000000000000000000000000000011 Result
  }
  ...
end;
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;
option1 := 0 in TIntegerSet(options); { Bit 0 is set? }
option3 := 2 in TIntegerSet(options); { Bit 2 is set? }
不同的
选项\uu
常量实际上用于将位屏蔽为零(检查是否设置了特定位)或将位屏蔽为1(设置特定位)

考虑一下这个片段:

begin
  ..

  if cbOptionX.Checked then
    Options := Options or OPTION_X;
  ..
将第一位屏蔽为1。如果我们从选项值(二进制)01010000开始,得到的选项将是01010001

    01010000   
 OR 00000001  //OPTION_X 
  = 01010001   
相同的值用于将所有其他位屏蔽为0,以检查是否设置了特定位。
if
条件,例如:
(选项和选项_Z)=OPTION_Z
,执行以下操作:

  • 首先,它将选项变量的所有不感兴趣的字节屏蔽为0。如果我们考虑最后一个值为01010001,则操作将导致清除所有位,但第一个。
        01010001   
    AND 00000001   
      = 00000001   
    
考虑到起始值01010000,它将返回零:

        01010000   
    AND 00000001   
      = 00000000   
  • 接下来,比较该值是否等于掩码本身。如果相等,则在原始选项变量中设置该位,否则未设置该位。如果你的掩码只包含一个位,这是味道的问题,你可以只检查结果值是否,例如,不同于0,但是如果你的掩码包含多个位,并且你想检查是否所有位都已设置,你必须检查是否相等

Delphi具有位运算符,用于处理整数类型的单个位。查看
shl
shr
异或
运算符。要组合位,请使用
运算符。要测试位,请使用
运算符。例如,假设这些常数:

const
  Option1 = 0x0001;
  Option2 = 0x0002;
  Option3 = 0x0004;
运算符查看两个输入值的位,并在任一输入值具有
1
位的位置生成具有
1
位的输出值。因此,组合位将如下所示:

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;
var
  Value: Integer;
begin
  Value := Option1 or Option2;
  {
  00000000000000000000000000000001 Option1
  00000000000000000000000000000010 Option2
  -------------------------------- OR
  00000000000000000000000000000011 Result
  }
  ...
end;
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;
option1 := 0 in TIntegerSet(options); { Bit 0 is set? }
option3 := 2 in TIntegerSet(options); { Bit 2 is set? }
运算符查看两个输入值的位,并仅在两个输入值都有
1
位的位置生成具有
1
位的输出值,否则它将生成
0
位。因此,BIT测试如下所示:

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;
var
  Value: Integer;
begin
  Value := Option1 or Option2;
  {
  00000000000000000000000000000001 Option1
  00000000000000000000000000000010 Option2
  -------------------------------- OR
  00000000000000000000000000000011 Result
  }
  ...
end;
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;
option1 := 0 in TIntegerSet(options); { Bit 0 is set? }
option3 := 2 in TIntegerSet(options); { Bit 2 is set? }

Delphi有一个预定义的类型TIntegerSet,它允许使用set操作符。假设
options
是一个整数,您可以检查是否有任何位(基于0)设置如下:

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;
var
  Value: Integer;
begin
  Value := Option1 or Option2;
  {
  00000000000000000000000000000001 Option1
  00000000000000000000000000000010 Option2
  -------------------------------- OR
  00000000000000000000000000000011 Result
  }
  ...
end;
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;
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 }

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

请您提出一个具体问题。这里没有。我想了解如何读取从整数值设置的特定位,以及如何设置特定位。如果值为1+4=5,那么如何读取右侧的1位和3位是否设置为真或等于真。所以你要测试第0位和第2位。为此,您为位0编写
(x和1)0
,为位2编写
(x和4)0
。你应该更直接地问这个问题。X是一个正则整数还是字节变量?@DavidHeffernan,谢谢。我会用SHL和SHR做什么?虽然所有的答案都很有用,UWA Rabee给出了最简单的答案,但我需要理解面具的概念@贾斯盖特,非常感谢。比我想象的要简单得多。测试0要好得多,因此避免违反DRY。我阅读了测试单个位的代码。我的评论适用于此。@jachguate,我可以在一次操作中检查多个位吗?@l了解您的if看起来不错。为什么要遍历所有位值?