XML位操作Delphi
我是一名高中生,目前在德尔福XE3学习。我们正在学习位操作。我们有一个作业,虽然我读了很多关于这个主题的书,并且理解了以Bits和SHL/SHR存储信息的整个过程,但我很难理解如何在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
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
AND 00000001
= 00000000
- 接下来,比较该值是否等于掩码本身。如果相等,则在原始选项变量中设置该位,否则未设置该位。如果你的掩码只包含一个位,这是味道的问题,你可以只检查结果值是否,例如,不同于0,但是如果你的掩码包含多个位,并且你想检查是否所有位都已设置,你必须检查是否相等
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看起来不错。为什么要遍历所有位值?