【问题标题】:Reading bit by bit out of bytes - simplification/speed-up suggestions - Delphi逐位读取字节 - 简化/加速建议 - Delphi
【发布时间】:2014-11-28 01:27:09
【问题描述】:

我有一个设备发送几个字节的状态信息,前 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 位字符串的函数...

是否有另一种“更简单”、更简化且(我真正感兴趣的)更快的程序来实现我的需要,或者这种方式是否足够好?

我觉得它有点迟钝和肮脏......:/(虽然最终,它的意图......所以感兴趣主要是出于学习的角度)

【问题讨论】:

    标签: delphi byte bit delphi-xe3


    【解决方案1】:

    这样你就可以直接从 AData 转换为布尔数组:

    for i := 0 to 39 do
      bits[i] :=  (AData[i div 8] and (1 shl (i mod 8))) <> 0;
    

    我不确定布尔值的顺序是否完全相同,我失去了所有索引的计数:)

    【讨论】:

    • 哈哈,不用担心。如有必要,我将检查并更正索引...这些是计算出来的,因为设备计数非常奇怪的是位向前但字节向后,所以我不得不重新排列... :) 谢谢这个!我知道可能有一种方法可以改变,但我完全不熟悉它的用法...... :)
    【解决方案2】:

    另一种方法是使用集合:

    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;
    

    【讨论】:

    • 支持另一种可能的清洁解决方案!我将使用公认的方法,因为我已经根据需要采用了它,但是这个方法也很好。
    • 它是否记录在任何可以像这样安全地投射集合的地方。字节序问题如何?
    • @DavidHeffernan,至少有 TIntegerSet:docwiki.embarcadero.com/Libraries/XE7/en/…。字节序应该没有问题,因为它会自行调整编译器如何实现集合。
    猜你喜欢
    • 2012-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-27
    • 1970-01-01
    相关资源
    最近更新 更多