8

我的应用程序是用 Delphi5 编写的。我正在使用 madExcept 来追踪错误。我找到了一个“零浮点除法”异常,它不应该出现在哪里。引发它的代码段如下所示:

val:=100*Power(1.25,c);

其中“c”实际上总是具有值“1”。

日志的堆栈跟踪:

main thread ($338f8):
00403504 +010 MyApp.exe   System   1970  +5 @FRAC
00479148 +058 MyApp.exe   Math              Power
007ae8a6 +262 MyApp.exe   MyClass  1962 +36 TMyClass.FormMouseWheel

我在某个时候遇到了另一个异常,确实发生了除法,但是除数是一个变量,当异常发生时它的值也为“1”。我能够调试和重现。

我的问题:我错过了什么?是否有一些我不知道的关于浮点除法的误报?

此外:我没有在异常点使用任何 C++ DLL,因为它们倾向于以不同的方式处理 FP 除法(返回 NaN 或 +/-INF 而不是引发异常)。

任何指针表示赞赏。

4

3 回答 3

8

我刚刚尝试了以下代码:

procedure TTTest.FormCreate(Sender: TObject);
var v: extended;
    one: extended;
begin
  one := 1.0;
  v := 100*Power(1.25,one);
end;

它只是在 Delphi 5 中按预期编译和运行。

我的猜测是每个零标志的除法可能设置在您的代码之外(即使您没有链接到 C++ 代码,调用 Direct X 或类似的可能具有相同的效果),但稍后在_Frac.

Frac在标准实现中唯一的调用Power()是 test Frac(Exponent) = 0.0

FracDelphi 5 和 Delphi 6 之间的实现有一个修改。

这是 Delphi 5 版本:

procedure       _FRAC;
asm
    FLD     ST(0)
    SUB     ESP,4
    FSTCW   [ESP]
    FWAIT
    FLDCW   cwChop
    FRNDINT
    FWAIT
    FLDCW   [ESP]
    ADD     ESP,4
    FSUB
end;

这是 Delphi 6 版本:

procedure       _FRAC;
asm
    FLD     ST(0)
    SUB     ESP,4
    FNSTCW  [ESP].Word     // save
    FNSTCW  [ESP+2].Word   // scratch
    FWAIT
    OR      [ESP+2].Word, $0F00  // trunc toward zero, full precision
    FLDCW   [ESP+2].Word
    FRNDINT
    FWAIT
    FLDCW   [ESP].Word
    ADD     ESP,4
    FSUB
end;

从上面的代码中,你会发现在 Delphi 6 发布之前,以下命令导致了延迟异常:Trunc、Frac、Ceil。

所以我猜你在使用 Delphi 5 时遇到了问题,Delphi 6 已经修复了这个问题。你可能必须使用自己的 Power 版本,比如这个:

function Power(Base, Exponent: Extended): Extended;
begin
  if Exponent = 0.0 then
    Result := 1.0               { n**0 = 1 }
  else if (Base = 0.0) and (Exponent > 0.0) then
    Result := 0.0               { 0**n = 0, n > 0 }
  else
    Result := Exp(Exponent * Ln(Base))
end;
于 2011-11-08T09:03:38.340 回答
2

无论如何都不是一个确定的答案,但是...

不应该出现的与 FPU 相关的异常可能与未正确清除 FPU 堆栈有关。尽管我们遇到了 Invalid Floating Point Operation 异常,但我们在某个阶段也遇到过类似的问题。

这篇文章:Delphi 今日错误:FPU 堆栈泄漏 ,其中有人追踪了引发 Invalid Floating Point Operation 异常的原因S := S + '*';,帮助我们解决了这个问题。

于 2011-11-08T08:36:16.187 回答
0

您使用的是 TWebBrowser 还是任何像 EmbeddedWB 这样的 IE 网络浏览器组件?

如果是这样,这可能会解释它: https ://forums.embarcadero.com/thread.jspa?messageID=334125&tstart=0

它还包含一些可能解决问题的内容,即使您没有使用上面 Jeroen 提供的链接所描述的网络浏览器 (Set8087CW)。

于 2011-11-08T13:24:23.760 回答