字节数组到Delphi中的有符号整数

时间:2015-05-31 03:59:06

标签: delphi

源数组(4个字节)

[$80,$80,$80,$80] =integer 0
[$80,$80,$80,$81] = 1
[$80,$80,$80,$FF] = 127
[$80,$80,$81,$01] = 128

需要将其转换为整数。

下面是我的代码及其目前的工作情况。

function convert(b: array of Byte): Integer;
var
  i, st, p: Integer;
  Negative: Boolean;
begin
  result := 0;
  st := -1;
  for i := 0 to High(b) do
  begin
    if b[i] = $80 then Continue // skip leading 80
    else
    begin
      st := i;
      Negative := b[i] < $80;
      b[i] := abs(b[i] - $80);
      Break;
    end;
  end;
  if st = -1 then exit;
  for i := st to High(b) do
  begin
    p := round(Power(254, High(b) - i));
    result := result + b[i] * p;
    result := result - (p div 2);
  end;
  if Negative then  result := -1 * result
end;

我正在寻找更好的功能?

更新

文件链接 https://drive.google.com/file/d/0ByBA4QF-YOggZUdzcXpmOS1aam8/view?usp=sharing

  • 在上传的文件ID字段中,偏移量为5到9


现在我遇到了解码日期字段的新问题 日期字段hex [$ 80,$ 8F,$ 21,$ C1] - &gt;可能日期1995-12-15
*在上传的文件中,日期字段偏移量为199到203

1 个答案:

答案 0 :(得分:1)

仅仅是大卫概述的一些改进的例子。

  • 数组通过引用传递为const。
  • 阵列大小固定。
  • 浮点计算的使用将直接转换为常量数组。
Const
  MaxRange = 3;
Type
  TMySpecial = array[0..MaxRange] of Byte;

function Convert(const b: TMySpecial): Integer;
var
  i, j: Integer;
  Negative: Boolean;
Const
  // Pwr[i] = Round(Power(254,MaxRange-i));
  Pwr: array[0..MaxRange] of Cardinal = (16387064,64516,254,1);
begin
  for i := 0 to MaxRange do begin
    if (b[i] <> $80) then begin
      Negative := b[i] < $80;
      Result := Abs(b[i] - $80)*Pwr[i] - (Pwr[i] shr 1);
      for j := i+1 to MaxRange do
        Result := Result + b[j]*Pwr[j] - (Pwr[j] shr 1);
      if Negative then
        Result := -Result;
      Exit;
    end;
  end;
  Result := 0;
end;

请注意,较少的代码行并不总是表现良好的标志。 始终在优化代码之前测量性能,以便找到真正的瓶颈。 代码可读性通常比优化代码更好。

为了将来参考,请告诉我们该算法应该做什么。

测试代码:

const
  X : array[0..3] of TMySpecial =
    (($80,$80,$80,$80), // =integer 0
     ($80,$80,$80,$81), // = 1
     ($80,$80,$80,$FF), // = 127
     ($80,$80,$81,$01)); // = 128
var
  i,j: Integer;
  sw: TStopWatch;
begin
  sw := TStopWatch.StartNew;
  for i := 1 to 100000000 do
    for j := 0 to 3 do
      Convert(X[j]);
  WriteLn(sw.ElapsedMilliseconds);
  ReadLn;
end.