Trunc() 在 64 位编译中对高 Int64 失败

4
为什么以下代码在64位编译中失败(但在32位编译中有效)?
var
  TruncTmp: Extended;
begin
  TruncTmp := 9223372036854775296;
  TruncTmp := Trunc(TruncTmp); // this fails on 64-bit
  Assert(TruncTmp = 9223372036854775296);
end;

在$0000000000405D70处发生了第一次异常。异常类$c0000090,错误信息是'c0000090 FLOAT_INVALID_OPERATION'。

这是一个Bug,还是我遗漏了什么?

注:

  • 我使用的是Delphi 10.2
  • 数字小于9223372036854775296都可以正常工作
1个回答

12

Win64没有“扩展”(80位浮点数)类型 - 它只是“double”(64位浮点数)的别名。因此,在双精度中您只有53个比特的分辨率。

所以我的猜测是,在您的情况下,这是预期的结果。


谢谢。现在我在RAD Studio文档中找到了信息:System.Extended - TmTron
1
准确来说,存储的值实际上是9223372036854775808,这个值比INT64(=9223372036854775807)能够存储的值要大。 - Uwe Raabe
@UweRaabe:这实际上是无效操作异常的真正原因。当然,这是由于只有53位可用于精度的事实所导致的结果。 - Rudy Velthuis
2
这是精度损失的原因,而不是异常的原因。 - MBo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接