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

时间:2011-05-20 20:28:47

标签: 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;

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

3 个答案:

答案 0 :(得分: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.

答案 1 :(得分:4)

我必须不同意Val解决了这个问题。 当用Hex编写时,Val仅适用于大的UInt64值。当它们以十进制形式写入时,最后一个字符将从字符串中删除,结果值是错误的。

参见Quality Central 108740: System.Val has problems with big UInt64 values 编辑:似乎这个问题应该在XE4中解决。无法测试。

答案 2 :(得分:3)

使用Value a UINT64,下面的代码片段给出了Delphi 2010的预期答案,但前提是输入值是十六进制

  stringValue := '$FFFFFFFFFFFFFFFF';
  val( stringValue, value, code );

  ShowMessage( UIntToStr( value ));

我只是简单地将val包装在一个便利功能中,你就完成了。

现在随时烧我。我在测试中错过了一个数字吗? :d