Delphi5中的浮点除零异常
我的应用程序是用Delphi5编写的。我用madExcept来追踪虫子。我跟踪到了一个“浮点零差”异常,它不应该出现在这个异常中。引发代码段的代码段如下所示:Delphi5中的浮点除零异常,delphi,floating-point,division,delphi-5,divide-by-zero,Delphi,Floating Point,Division,Delphi 5,Divide By Zero,我的应用程序是用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 Pow
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分区不同(返回楠或+/-INF而不是引发异常)。
感谢您的指点。无论如何,这不是一个明确的答案,但 不应该存在的Fpu相关异常可能与未正确清除Fpu堆栈有关。我们在某个阶段遇到了类似的问题,尽管我们遇到了无效的浮点操作异常
本文:有人找到了由
S:=S+'*'引发的无效浮点操作异常的原因代码>,帮助我们解决了问题。我刚刚尝试了以下代码:
procedure TTTest.FormCreate(Sender: TObject);
var v: extended;
one: extended;
begin
one := 1.0;
v := 100*Power(1.25,one);
end;
它只是按照Delphi5中的预期编译和运行
我猜想,每一个零标记可以设置在代码之外(即使你不链接到C++代码,调用直接X,或者可能会有同样的效果),但是后来在p>
在Power()
的标准实现中,对Frac
的唯一调用是测试Frac(index)=0.0
Delphi 5和Delphi 6之间对Frac
的实现进行了修改
以下是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;
从上面的代码中,您将发现以下命令导致在Delphi6发布之前引发延迟异常:Trunc、Frac、Ceil
所以我猜您在Delphi5中遇到了一个问题,Delphi6已经解决了这个问题。您可能需要使用自己版本的电源,例如:
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;
您是否使用TWebBrowser或任何IE webbrowser组件,如EmbeddedWB
如果是这样,这或许可以解释:
它还包含一些可能解决问题的内容,即使您没有使用上面Jeroen提供的链接所描述的webbrowser(Set8087CW)。听起来不太可信。我认为您的调试工具没有将您指向正确的位置,或者可能变量没有包含您所认为的内容。不记得D5是否已经拥有它,但您是否尝试过在执行代码时检查CPU/FPU视图中发生了什么?@ldsandon当然D5已经允许使用Alt-F2并进入CPU/FPU视图。好主意。但我猜未处理的FPU异常将在系统中中断。\u Frac
code。您是否使用任何外部DLL?如果是这样,他们可能已经更改了FPU控制字。在更多信息上看到这篇帖子:很好的答案,为我指出了问题所在。虽然有点吹毛求疵,但答案可以通过解释每一条装配线在做什么来改进——至少对于关键的装配线是这样。或者,总结每个压裂程序的作用(将旧CW推到堆栈上,设置新CW,执行操作,从堆栈中弹出旧CW,诸如此类)。对我们这些不精通x86汇编的人会有所帮助。:)