当我尝试Trunc()
一个Real
值时,我得到一个(可重复的)浮点异常.
例如:
Trunc(1470724508.0318);
Run Code Online (Sandbox Code Playgroud)
实际上,实际代码更复杂:
ns: Real;
v: Int64;
ns := ((HighPerformanceTickCount*1.0)/g_HighResolutionTimerFrequency) * 1000000000;
v := Trunc(ns);
Run Code Online (Sandbox Code Playgroud)
但最终它仍归结为:
Trunc(ARealValue);
Run Code Online (Sandbox Code Playgroud)
现在,我不能在其他任何地方重复它 - 就在这一点.每次失败的地方.
幸运的是计算机并不神奇.英特尔CPU执行非常具体的可观察操作.所以我应该能够找出浮点运算失败的原因.
进入CPU窗口
v:= Trunc(ns)
Run Code Online (Sandbox Code Playgroud)fld qword ptr [ebp-$10]
这会将ebp- $ 10处的8字节浮点值加载到浮点寄存器中ST0
.
内存地址[ebp- $ 10]的字节数为:
0018E9D0: 6702098C 41D5EA5E (as DWords)
0018E9D0: 41D5EA5E6702098C (as QWords)
0018E9D0: 1470724508.0318 (as Doubles)
Run Code Online (Sandbox Code Playgroud)
调用成功,浮点寄存器包含适当的值:
接下来是对RTL Trunc函数的实际调用:
call @TRUNC
Run Code Online (Sandbox Code Playgroud)
接下来是Delphi RTL的Trunc功能:
@TRUNC:
Run Code Online (Sandbox Code Playgroud)sub esp,$0c wait fstcw word ptr [esp] //Store Floating-Point Control Word on the …
在Delphi 2010和Delphi 2007中,我在WebBrowserBeforeNavigate/WebBrowserDocumentComplete上使用Set8087CW来防止ActiveX内的FPU错误导致我的应用程序瘫痪.
但不知何故,这在Delphi XE2中不起作用,至少在64位模式下是这样.
当点击链接(任何)时,我得到"浮动除以零".(将网站地址或内容初始加载到TWebBrowser中工作正常.)
callstack显示这发生在system32\D3D10Warp.dll内(可能由IE9使用?)以响应TApplication.ProcessMessage(以及两者之间的一些???)