逐位读取字节-简化/加速建议-Delphi

逐位读取字节-简化/加速建议-Delphi,delphi,byte,bit,delphi-xe3,Delphi,Byte,Bit,Delphi Xe3,我有一个设备,它可以发送几个字节的状态信息,前5个字节是40个按钮的状态。每个位代表一个按钮,1表示释放,0表示按下 从那件事开始,我使用以下代码进行结账: procedure TForm2.ServerUDPRead(AThread: TIdUDPListenerThread; AData: array of Byte; ABinding: TIdSocketHandle); var received: array [0..4] of string; a1, a2 integer; bit

我有一个设备,它可以发送几个字节的状态信息,前5个字节是40个按钮的状态。每个位代表一个按钮,1表示释放,0表示按下

从那件事开始,我使用以下代码进行结账:

procedure TForm2.ServerUDPRead(AThread: TIdUDPListenerThread;
  AData: array of Byte; ABinding: TIdSocketHandle);
var received: array [0..4] of string; a1, a2 integer;
bits: array [0..40] of boolean;
begin

for a1 := 0 to 4 do
  Received[a1] := (ByteToBin(AData[a1]));

for a1 := 4 downto 0 do
  begin
    for a2 := 1 to 8 do
      begin
        if Copy(Received[a1], a2, 1) = '0' then bits[(4-a1)*8+(a2-1)]:=False else bits[(4-a1)*8+(a2-1)]:=True;
      end;
  end;
ByteToBin是将字节转换为8位字符串的函数

是否有一个替代的“更简单”,简化和(我真正感兴趣的)更快的程序来实现我所需要的,或者这种方式足够好吗


我发现它有点迟钝和肮脏…:/(虽然最终,它的意图……主要是出于学习的角度而感兴趣)

有了它,您可以直接从AData转换为布尔数组:

for i := 0 to 39 do
  bits[i] :=  (AData[i div 8] and (1 shl (i mod 8))) <> 0;
对于i:=0到39 do
位[i]:=(数据[i div 8]和(1 shl(i mod 8)))0;

我不确定布尔值的顺序是否完全相同,我无法计算所有索引:)

另一种方法是使用集合:

type
  TByteSet = set of 0..7;
...
  for I := 0 to 39 do begin
    bits[I] := (I mod 8) in TByteSet(AData[I div 8]);
  end;

哈哈,不用担心。如果有必要,我会检查并更正索引。。。这些都是计算出来的,因为设备的计数非常奇怪,向前一位,向后一个字节,所以我不得不重新排列…:)谢谢这个!我知道有一种方法可以改变,但我完全不熟悉它的用法…:)请投票选择另一种可能的清洁解决方案!我将使用公认的方法,因为我已经根据自己的需要采用了它,但这一方法也很好。它是否有文档记录,可以在任何地方安全地进行这样的转换。endianness问题呢?@DavidHeffernan,至少有TIntegerSet:。endianess应该没有问题,因为它会自行调整编译器实现集合的方式。