Delphi Val不适用于UInt64?

Delphi Val不适用于UInt64?,delphi,delphi-xe2,Delphi,Delphi Xe2,只是好奇为什么下面的代码无法转换字符串表示形式中的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(

只是好奇为什么下面的代码无法转换字符串表示形式中的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.
var
num:UInt64;
s:字符串;
err:整数;
开始
s:=“18446744073709551615”;//高(UInt64)
Val(s,num,err);
如果错误为0,则
引发异常。Create('未能在'+IntToStr(err)]转换UInt64;//返回20
结束。
德尔福XE2

我是不是遗漏了什么

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

我同意文件有点模糊;事实上,form到底意味着什么,有符号实数到底意味着什么(特别是当
num
是整数类型时)

不过,我认为要强调的部分已经签署。在本例中,您需要一个整数,因此
S
必须是构成有符号整数的字符序列。但是您的最大值是
高(Int64)=9223372036854775807
您是对的:
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和非Unicode版本的Delphi中工作


错误时,它返回0。

这方面的文档确实缺乏,但我使用
System.SysUtils
中的
strotuint64
uintotstr
,它们在字符串和无符号64位整数之间转换

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

我不确定这些是什么时候添加到Delphi的,但它们肯定是在最近的几个版本中。

Val
是解析为
系统的内在特性。_ValInt64
当传递一个8字节宽的整数时。和
\u ValInt64
返回有符号整数。文档很可怜。据我所知,没有内置的例程将字符串转换为UInt64。你得自己写!这个问题()涵盖了相同的主题。我也回答了+1,但只有一个问题。64位编译器不会因为第一个
指针
强制转换而失败吗?在我看来这是一个打字错误,你不想在那里使用
PChar
吗?@TLama为什么?指针强制转换对于32位和64位编译器完全相同。就我个人而言,我会使用S[I],但这主要只是偏好。@David,是的,我后来意识到(但忘了删除该注释…)在错误时返回零并没有太大用处。它确实应该处理超出范围的输入。@DavidHeffernan我有几个这样的函数变体,其中一个使用了
var error:integer
附加参数。根据上下文(例如在我们的mORMot框架中),返回0是有意义的。这只是为了展示一种实现模式@TLama这段代码将从Delphi2一直工作到XE2,包括64位版本的XE2,我想也是FPC。