如何快速将数字字符数组转换为整数?

时间:2011-02-27 19:17:22

标签: delphi performance

情况:整数以字节数组(TBytes)保存为十六进制。将该数字转换为类型为整数且复制较少,如果可能,不进行任何复制。

这是一个例子:

array = ($35, $36, $37);

这是ansi中的'5','6','7'。如何将它转换为567(= $ 273)而不会遇到麻烦?

我是通过复制两次来做到的。是否可以更快地完成?怎么样?

4 个答案:

答案 0 :(得分:1)

您可以使用 LookUp表代替HexToInt ...

此程序仅适用于AnsiChars,当然不提供错误检查!

var
  Table        :array[byte]of byte;

procedure InitLookupTable;
var
  n:            integer;
begin
  for n := 0 to Length(Table) do
    case n of
      ord('0')..ord('9'): Table[n] := n - ord('0');
      ord('A')..ord('F'): Table[n] := n - ord('A') + 10;
      ord('a')..ord('f'): Table[n] := n - ord('a') + 10;
    else Table[n] := 0;
    end;
end;

function HexToInt(var hex: TBytes): integer;
var
  n:            integer;
begin
  result := 0;
  for n := 0 to Length(hex) -1 do
    result := result shl 4 + Table[ord(hex[n])];
end;

答案 1 :(得分:0)

function BytesToInt(const bytes: TBytes): integer;
var
  i: integer;
begin
  result := 0;
  for i := 0 to high(bytes) do
    result := (result shl 4) + HexToInt(bytes[i]);
end;

正如PA指出的那样,当然会有足够的数字溢出。 HexToInt的实现留给读者,错误处理也是如此。

答案 2 :(得分:0)

你可以做到

function CharArrToInteger(const Arr: TBytes): integer;
var
  s: AnsiString;
begin
  SetLength(s, length(Arr));
  Move(Arr[0], s[1], length(s));
  result := StrToInt(s);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  a: TBytes;
begin
  a := TBytes.Create($35, $36, $37);
  Caption := IntToStr(CharArrToInteger(a));
end;

如果你知道字符串是以null结尾的,也就是说,如果数组中的最后一个字符是0,那么你可以这样做

function CharArrToInteger(const Arr: TBytes): integer;
begin
  result := StrToInt(PAnsiChar(@Arr[0]));
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  a: TBytes;
begin
  a := TBytes.Create($35, $36, $37, 0);
  Caption := IntToStr(CharArrToInteger(a));
end;

然而,最自然的方法是使用字符数组而不是字节数组!然后编译器可以为你做一些技巧:

procedure TForm1.FormCreate(Sender: TObject);
var
  a: TCharArray;
begin
  a := TCharArray.Create(#$35, #$36, #$37);
  Caption := IntToStr(StrToInt(string(a)));
end;

答案 3 :(得分:0)

它不能比那更快; - )

function HexToInt(num:pointer; size:Cardinal): UInt64;
var i: integer;
    inp: Cardinal absolute num;
begin
  if(size > SizeOf(Result)) then Exit;
  result := 0;
  for i := 0 to size-1 do begin
    result := result shl 4;
    case(PByte(inp+i)^) of
      ord('0')..ord('9'): Inc(Result, PByte(inp+i)^ - ord('0'));
      ord('A')..ord('F'): Inc(Result, PByte(inp+i)^ - ord('A') + 10);
      ord('a')..ord('f'): Inc(Result, PByte(inp+i)^ - ord('a') + 10);
    end;
  end;
end;
function fHexToInt(b:TBytes): UInt64; inline;
begin
  Result:=HexToInt(@b[0], Length(b));
end;

...
b:TBytes = ($35, $36, $37);
HexToInt(@b[0], 3);
fHexToInt(b);