加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Delphi5中的浮点除零异常

发布时间:2020-12-15 04:03:49 所属栏目:大数据 来源:网络整理
导读:我的应用程序是用Delphi5编写的.我正在使用madExcept来追踪错误.我追踪了一个“浮点dvision by zero”异常,它不应该是.引发它的代码段如下: val:=100*Power(1.25,c); 其中’c’实际上总是有值’1′. 日志的堆栈跟踪: main thread ($338f8):00403504 +010 M
我的应用程序是用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而不是引发异常).

任何指针赞赏.

解决方法

我刚刚尝试了以下代码:
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中提出.

在Power()的标准实现中对Frac的唯一调用是测试Frac(指数)= 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;

从上面的代码中,您将发现以下命令在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;

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读