Delphi5中浮点除零异常

时间:2011-11-08 08:10:40

标签: delphi floating-point division delphi-5 divide-by-zero

我的应用程序是用Delphi5编写的。我正在使用madExcept来追踪错误。我追踪了一个“浮点dvision by zero”异常,它不应该是。引发它的代码段如下:

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而不是引发异常)。

任何指示赞赏。

3 个答案:

答案 0 :(得分: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等可能会产生相同的效果),但稍后会在{{1}中提出}。

_Frac标准实施中对Frac的唯一调用是测试Power()

Delphi 5和Delphi 6之间Frac(Exponent) = 0.0的实现有一个修改。

以下是Delphi 5版本:

Frac

以下是Delphi 6版本:

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发布之前引发延迟异常:Trunc,Frac,Ceil。

所以我猜你遇到了Delphi 5的问题,Delphi 5已经修复了Delphi 6.您可能需要使用自己的Power版本,如下所示:

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;

答案 1 :(得分:2)

无论如何都不是明确的答案,但是......

不存在的Fpu相关异常可能与FPU堆栈无法正确清除有关。虽然我们遇到了无效的浮点运算异常,但我们在一个阶段遇到了类似的问题。

这篇文章:Delphi bug of the day: FPU stack leak有人追踪S := S + '*';引发的无效浮点操作异常的原因,帮助我们解决了这个问题。

答案 2 :(得分:0)

您使用的是TWebBrowser还是任何IE浏览器组件,如EmbeddedWB?

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

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