Delphi:如何从TBytes读取X位?
我遇到了一个与从TB中读取随机数位数有关的问题。首先,我遵循了这个问题的建议(关于使用ubitstream.pas单元的答案): 我的例子是: 二进制馈送(TBytes)=(255,0,0,0,0,0,6,132,1112,128,128,130,81)Delphi:如何从TBytes读取X位?,delphi,bit-manipulation,byte,bytearray,Delphi,Bit Manipulation,Byte,Bytearray,我遇到了一个与从TB中读取随机数位数有关的问题。首先,我遵循了这个问题的建议(关于使用ubitstream.pas单元的答案): 我的例子是: 二进制馈送(TBytes)=(255,0,0,0,0,0,6,132,1112,128,128,130,81) 我读8位,得到255-ok。位置是8 我读了另外24位,得到0-ok。位置是32 我又读了24位,得到393216而不是6。位置是56 393216是0000 01100000 我能理解为什么会发生这种情况,但我不知道如何截断这些额外的零位。有
00000000 00000000 00000110
也就是6
您正在使用的代码是小端,但您希望有大端行为。您需要更改代码以解释此不匹配
从我们在问题中看到的情况来看,您总是在读取整个字节,因此不需要考虑所使用代码的复杂性。您可以在字节级别进行操作。显然,您仍然需要正确解释endianness,但这不是很有挑战性。问题是
电话号码是393216。把这三个字节倒过来,你就有了
00000000 00000000 00000110
也就是6
您正在使用的代码是小端,但您希望有大端行为。您需要更改代码以解释此不匹配
从我们在问题中看到的情况来看,您总是在读取整个字节,因此不需要考虑所使用代码的复杂性。您可以在字节级别进行操作。显然,您仍然需要正确解释endianness,但这不是很有挑战性。首先考虑您的容器。如果将字节读入32位整数,则应使用shr/shl将位移动到位。 shl将您不希望的大部分位保留在32位范围之外,然后shr剩余的X个位置以获得字节值(或字,或任何您需要的大小),这种情况并不少见 在上面的代码中,我们不希望包含前8位,所以我们将整个内容向左移动8位,然后向后移动8位。当位从容器的“边缘”移开时,这会将位归零 使用SHL和SHR在变量内移动位/字节。但请记住容器的大小。字(16位)、整数(32位)等
您还可以使用AND和OR掩码来实现一些相同的功能,尽管对于与CPU寄存器大小相同(32位或64位)的变量,SHL和SHR通常更快。首先考虑容器。如果将字节读入32位整数,则应使用shr/shl将位移动到位。 shl将您不希望的大部分位保留在32位范围之外,然后shr剩余的X个位置以获得字节值(或字,或任何您需要的大小),这种情况并不少见 在上面的代码中,我们不希望包含前8位,所以我们将整个内容向左移动8位,然后向后移动8位。当位从容器的“边缘”移开时,这会将位归零 使用SHL和SHR在变量内移动位/字节。但请记住容器的大小。字(16位)、整数(32位)等
您也可以使用AND和OR掩码来实现一些相同的功能,尽管对于与CPU寄存器大小相同(32位或64位)的变量,SHL和SHR通常更快。这个“随机位数”,总是8位的倍数吗?如果是,那么您可以读取字节。如果这是big-endian,那么多个字节通过如下方式组合成整数:
value:=nextByte+value*256;numBits:=numBits-8重复编码>直到你有了位数。如果你要找的是真正的“位访问”(看起来不像,请参阅@DavidHeffernan的答案),你应该看看System.Classes.Past中Delphi的TBits类这个“随机位数”,它总是8位的倍数吗?如果是,那么您可以读取字节。如果这是big-endian,那么多个字节通过如下方式组合成整数:value:=nextByte+value*256;numBits:=numBits-8重复编码>直到得到位数。如果您要查找的是真正的“位访问”(看起来不像,请参阅@DavidHeffernan的答案),那么您应该在System.Classes.pas>>中查看Delphi的TBits类,尽管我们在问题中看到了,您总是在读取整个字节,因此不需要考虑所使用代码的复杂性。我需要支持读取,例如3位。好吧,问题不清楚,因为你总是以8的倍数读取位。重点仍然是endianness是一个问题。>>但从我们在问题中看到的情况来看,您总是读取整个字节,因此不需要使用复杂的代码。我需要支持读取,例如3位。好吧,问题不清楚,因为你总是以8的倍数读取位。重点仍然是,持久性是问题所在。
var
value: integer;
begin
value := (Readint32FromBuffer shl 8) shr 8;
writeln(value.tostring);
end;