我想将大的 64 位值从十进制或十六进制字符串转换为 64 位 UINT64 数据类型。有一个 UIntToStr 可以帮助将 UINT64 转换为字符串,但无法将 64 位整数转换为无符号值(作为字符串)。这意味着大于 2**63 的整数值不能使用 RTL 以十进制或十六进制表示。这通常不是什么大问题,但用户可能需要输入一个无符号整数值,该值必须作为 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 十进制值时存在问题。
最佳答案
更新:在 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.
关于delphi - delphi中有一个UIntToStr可以让你显示UINT64值,但是StrToUInt在哪里允许用户输入64位无符号值呢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6077258/