问题描述
|
我想将较大的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;
Update 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.
,我必须不同意Val解决这个问题。
Val以十六进制编写时,仅适用于较大的UInt64值。当它们以十进制表示时,最后一个字符将从字符串中删除,并且结果值错误。
请参阅Quality Central 108740:System.Val具有较大的UInt64值问题
编辑:似乎这个问题应该在XE4中解决。无法测试。
,使用Value a UINT64时,以下代码段仅在输入值是十六进制的情况下才能在Delphi 2010上提供预期的答案
stringValue := \'$FFFFFFFFFFFFFFFF\';
val( stringValue,value,code );
ShowMessage( UIntToStr( value ));
我只是将val包装在一个便捷函数中,您就完成了。
现在随便烧死我。我的考试中缺少数字吗? :D