提问者:小点点

Val不适用于UInt64?


只是好奇为什么以下代码无法在字符串表示中转换uint64值?

var
  num: UInt64;
  s: string;
  err: Integer;

begin
  s := '18446744073709551615';  // High(UInt64)
  Val(s, num, err);
  if err <> 0 then
    raise Exception.Create('Failed to convert UInt64 at ' + IntToStr(err));  // returns 20
end.

德尔福XE2

我错过了什么吗?


共3个答案

匿名用户

您是对的:Val()UInt64/QWord不兼容。

有两个重载函数:

  • 一个返回浮点值;
  • 返回一个Int64(即有符号值)。

您可以改用此代码:

function StrToUInt64(const S: String): UInt64;
var c: cardinal;
    P: PChar;
begin
  P := Pointer(S);
  if P=nil then begin
    result := 0;
    exit;
  end;
  if ord(P^) in [1..32] then repeat inc(P) until not(ord(P^) in [1..32]);
  c := ord(P^)-48;
  if c>9 then
    result := 0 else begin
    result := c;
    inc(P);
    repeat
      c := ord(P^)-48;
      if c>9 then
        break else
        result := result*10+c;
      inc(P);
    until false;
  end;
end;

它可以在Unicode版本和Delphi的Unicode版本中工作。

错误时,它返回0。

匿名用户

根据留档,

S是字符串类型的表达式;它必须是形成有符号实数的字符序列。

我同意留档有点模糊;事实上,form到底是什么意思,有符号实数到底是什么意思(尤其是如果num是整数类型)?

尽管如此,我认为要突出显示的部分是有符号的。在这种情况下,您需要一个整数,因此S必须是形成有符号整数的字符序列。但是你的最大值是High(Int64)=9223372036854775807

匿名用户

function TryStrToInt64(const S: string; out Value: Int64): Boolean;
var
  E: Integer;
begin
  Val(S, Value, E);
  Result := E = 0;
end;