在短暂查看system.math的源代码时,我发现64位版本的Delphi Tokyo 10.2.3将非正规的IEEE-Doubles刷新为零,从后面的程序可以看出;
{$apptype console}
uses
system.sysutils, system.math;
var
x: double;
const
twopm1030 : UInt64 = $0000100000000000; {2^(-1030)}
begin
x := PDouble(@twopm1030)^;
writeln(x);
x := ldexp(1,-515);
writeln(x*x);
x := ldexp(1,-1030);
writeln(x);
end.
Run Code Online (Sandbox Code Playgroud)
对于32位,输出是预期的
8.69169475979376E-0311
8.69169475979376E-0311
8.69169475979376E-0311
Run Code Online (Sandbox Code Playgroud)
但我得到了64位
8.69169475979375E-0311
0.00000000000000E+0000
0.00000000000000E+0000
Run Code Online (Sandbox Code Playgroud)
因此,东京基本上可以在64位模式下处理非正规数,常量被正确写入,但是从算术运算或甚至用ldexp,非正规结果被刷新为零.
可以在其他系统上确认这一观察结果吗?如果是,在哪里记录?(我能找到关于零冲洗的唯一信息是Denormals become zero when stored in a Real48).
更新:我知道,这两个 32位和64位的单超负荷使用.对于32位,使用x87 FPU,ASM代码对于所有精度(单,双,扩展)几乎相同.FPU总是返回一个80位扩展,它存储在一个double中而不会过早截断.64位代码在存储之前进行精确调整.与此同时,我提交了一份问题报告(https://quality.embarcadero.com/browse/RSP-20925),重点关注32位或64位的不一致结果.
IEEE Std 754-2008 在表 9.1 中列出了推荐的函数compound(x,n) = (1+x)^n,其中 x 为实数,n 为整数(其中^是幂运算符)。该域被指定为x in [-1, +infinity]和n in Z。当 x < -1 时,该函数应发出无效操作异常信号。
范围限制是否有一些众所周知但未列出的原因?数学上 (1+x)^n 对于所有 x != -1 都是明确定义的(如果 n > 0,甚至对于 x = -1)。
Delphi Tokyo 64-bit将使用单精度计算一些数学函数,如果使用整数常量调用,例如
{$apptype console}
uses
system.math;
var
d: double;
begin
d := 10;
writeln(log2(10):20:16, log2(10.0):20:16,log2(d):20:16);
end.
Run Code Online (Sandbox Code Playgroud)
将打印3.3219280242919923 3.3219280948873626 3.3219280948873626.
我被告知在Delphi东京64位刷新非正常数字为零?,我应该使用类型转换double(10)来解决此功能.问题是,从我可用的Delphi版本开始,只有东京允许这种类型转换(IMO,即使文档似乎禁止它,说只允许变体被转换为真实类型).
我知道,XE4(VER250)给出了错误Error: E2089 Invalid typecast的double(10),但我不知道VER260 .. VER310信息.
那么第一个允许类型转换的Delphi版本
double(10)呢?