在delphi中使用UIntToStr来显示UINT64值,但StrToUInt在哪里允许用户输入64位无符号值?

War*_* P 10 delphi delphi-xe

我想将一个大的64位值从十进制或十六进制字符串转换为64位UINT64数据类型.有一个UIntToStr可以帮助将UINT64转换为字符串,但没有办法将64位整数转换为无符号值,作为字符串.这意味着使用RTL不能用十进制或十六进制表示大于2**63的整数值.这通常不是什么大问题,但是可能发生用户需要输入一个值,作为无符号整数,必须作为64位无符号整数值存储到注册表中.

procedure HandleLargeHexValue;

var
 x:UINT64;
begin

  x := $FFFFFFFFFFFFFFFE;

  try
  x := StrToInt('$FFFFFFFFFFFFFFFF'); // range error.
  except
    x := $FFFFFFFFFFFFFFFD;
  end;

  Caption := UintToStr(x);

end;
Run Code Online (Sandbox Code Playgroud)

Update Val现在可以在Delphi XE4及更高版本中正常运行.在XE3及以下Val('$ FFFFFFFFFFFFFFFF')有效,但不是Val('9223372036854775899').正如Roeland在Quality Central 108740中指出的那样:在Delphi XE4之前,System.Val在十进制中存在大的UInt64值问题.

War*_* P 6

更新:在XE4及更高版本中修复了RTL错误.此hack仅在Delphi XE3或更早版本中有用

好吧,如果不存在,我想我总能写出来.

(我也为此写了一个非常好的单元测试,但它太大了,不能在这里发布)

unit UIntUtils;

{ A missing RTL function written by Warren Postma. }

interface
  function TryStrToUINT64(StrValue:String; var uValue:UInt64 ):Boolean;
  function StrToUINT64(Value:String):UInt64;

implementation

uses SysUtils,Character;

{$R-}

function TryStrToUINT64(StrValue:String; var uValue:UInt64 ):Boolean;
var
  Start,Base,Digit:Integer;
  n:Integer;
  Nextvalue:UInt64;
begin
  result := false;
  Base := 10;
  Start := 1;
  StrValue := Trim(UpperCase(StrValue));
  if StrValue='' then
    exit;
  if StrValue[1]='-' then
    exit;
  if StrValue[1]='$' then
  begin
    Base := 16;
    Start := 2;
    if Length(StrValue)>17 then // $+16 hex digits = max hex length.
        exit;
  end;
  uValue := 0;
  for n := Start to Length(StrValue) do
  begin
      if Character.IsDigit(StrValue[n]) then
          Digit := Ord(StrValue[n])-Ord('0')
      else if  (Base=16) and (StrValue[n] >= 'A') and (StrValue[n] <= 'F') then
          Digit := (Ord(StrValue[n])-Ord('A'))+10
      else
          exit;// invalid digit.

      Nextvalue := (uValue*base)+digit;
      if (Nextvalue<uValue) then
          exit;
      uValue := Nextvalue;
  end;
  result := true; // success.
end;

function StrToUINT64(Value:String):UInt64;
begin
  if not TryStrToUINT64(Value,result) then
    raise EConvertError.Create('Invalid uint64 value');

end;

end.
Run Code Online (Sandbox Code Playgroud)