Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Delphi:如何从TBytes读取X位?_Delphi_Bit Manipulation_Byte_Bytearray - Fatal编程技术网

Delphi:如何从TBytes读取X位?

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 我能理解为什么会发生这种情况,但我不知道如何截断这些额外的零位。有

我遇到了一个与从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

    我能理解为什么会发生这种情况,但我不知道如何截断这些额外的零位。有什么想法吗

    问题是

    电话号码是393216。把这三个字节倒过来,你就有了

    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;