我的应用程序是用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而不是引发异常)。
任何指示赞赏。
答案 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提供的链接所描述的内容。