【问题标题】:Invalid Floating Point Operation无效的浮点运算
【发布时间】:2015-11-26 22:52:35
【问题描述】:

我不断收到此错误“无效的浮点运算”。

我在 Delphi 7 上。

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
TlHelp32, Dialogs, StdCtrls, ExtCtrls, Buttons, ComCtrls;

var //global
PHandle, cancel, bytes, scantype: integer;

...

procedure Tmain.scanbtnClick(Sender: TObject);
    var max, address: Integer;
    floatinput, floatinput1, floatinput2, datafloat: Real;
    x: cardinal;
    itm: TListItem;
begin

  floatinput := StrToFloat(Trim(valueinput.Text));
  floatinput1 := StrToFloat(Trim(valueinput1.Text));
  floatinput2 := StrToFloat(Trim(valueinput2.Text));

  if floatinput2 < floatinput1 then
  begin
    floatinput1 := floatinput1 + floatinput2;
    floatinput2 := floatinput1 - floatinput2;
    floatinput1 := floatinput1 - floatinput2;
  end;

  result.Show;

  x := 0;
  address := 0;

  result.resultlist.Clear;

  repeat
    Application.ProcessMessages;
    statusbar1.Panels.Items[1].Text := 'Searching... ' + IntToStr(address * 100 div max) + '% (' + IntToStr(address div bytes) + ' out of ' + IntToStr(max div bytes) + ').';

    if ReadprocessMemory(PHandle, Ptr(address), @datafloat, bytes, x) then
      begin
        if (x > 0) then
        begin
          if scantype = 0 then
          begin
            if datafloat = floatinput then             //error here
            begin
              itm := result.resultlist.Items.Add;
              itm.Caption := '0x' + IntToHex(address,8);
              itm.SubItems.Add(FormatFloat('0.0#########', datafloat));
            end;
          end;
          if scantype = 1 then
          begin
            if datafloat > floatinput              //also here
            then begin
              itm := result.resultlist.Items.Add;
              itm.Caption := '0x' + IntToHex(address,8);
              itm.SubItems.Add(FormatFloat('0.0#########', datafloat));
            end;
          end;
          if scantype = 2 then
          begin
            if datafloat < floatinput     //here too
            then begin
              itm := result.resultlist.Items.Add;
              itm.Caption := '0x' + IntToHex(address,8);
              itm.SubItems.Add(FormatFloat('0.0#########', datafloat));
            end;
          end;
          if scantype = 2 then
          begin
            if (dataint <= intinput2) and (dataint >= intinput1)    //even here
            then begin
              itm := result.resultlist.Items.Add;
              itm.Caption := '0x' + IntToHex(address,8);
              itm.SubItems.Add(FormatFloat('0.0#########', datafloat));
            end;
          end;

        end;
      end;

    if x <> 0
    then address := address + x
    else address := address + bytes;

  until (address >= Max) or (cancel = 1);

end;

我什至检查了 cpu 窗口,这是因为它试图从指向空值的指针加载浮点值。

这不是 ReadMemory,因为这小段代码在 while 循环中,它在遇到此错误之前返回几个有效值。

我该怎么办?

提前致谢。

【问题讨论】:

  • datafloat 是什么数据类型?您将其与变体(Null)进行比较,但变体不是与 ReadProcessMemory 兼容的类型。您的意思是使用 Double 吗?
  • 您发布的代码将无法编译,因为在 Delphi 中,NULL 的唯一有效用途是在使用变体时。请发布您正在使用的完整的实际代码。要求我们调试实际上不是您的代码的代码既浪费您的时间,也浪费我们的时间。如果您需要帮助,请在此处发布可演示问题的可编译 MCVE。
  • @GerryColl datafloat 是真实的。你能解释一下当我尝试将一个值与 null 进行比较时到底发生了什么吗?
  • @KenWhite 完整的代码实际上有点大,没有必要用可能与问题无关的东西来填充主题。我可以提供哪些信息来帮助您看得更清楚?
  • 然后将其缩减为首先演示问题所需的最少代码。我们无法调试我们看不到的代码,或者无法编译的代码。正如我之前问过的,请发布一个我们可以使用的 MCVE。

标签: delphi point floating operation


【解决方案1】:

我们可以看到代码存在两个潜在问题。

首先你不要检查ReadProcessMemory的返回值。由于各种原因,该调用可能会失败。由于您不检查错误,因此您无法知道函数调用是否成功。始终检查 API 调用是否成功。阅读 MSDN 上的文档以了解如何执行此操作。通常这涉及检查函数返回值,就像这里的情况一样。如果函数失败,则浮点变量可能包含未初始化的数据,并可能出现错误。

另一个问题是datafloat 是通过从另一个进程读取字节来填充的。如果这些字节不代表有效的浮点值,那么如果您尝试对该值进行操作,则会引发异常。并非所有位模式都代表有效的浮点值。例如,您可能遇到了一个信号 NaN 值。也许您应该与CompareMem 进行比较,因为您似乎正在读取任意内存,看起来像是在对其他程序进行逆向工程。通过按位比较进行测试将避免将无效值加载到浮动寄存器中的风险。

最后,我不确定你所说的针对null 测试浮点值是什么意思,无论null 是什么。浮点值不能为空。你很可能在那里有一个重大的误解。

【讨论】:

  • 好的,所以我改变了我的代码,现在我只在 ReadProcessMemory 的结果为真时继续,然后我检查读取的字节数是否 > 0,即使我没有完全明白为什么,comparemem 例程有效,但是如果我想知道 datafloat > floatinput 怎么办?我不应该能够比较两个实际值吗?
  • 其实.. 不。即使它应该返回 true,CompareMem 也返回 false,当我使用正常比较时,它只返回它应该返回的值,但总是在一段时间后进入这个错误..
  • 好的,我修好了,你的回答真的很有用。我所做的是在使用中声明“数学”,然后使用 IsNan 例程检查“datafloat”是否不是 NaN,谢谢。
  • CompareMem 如果您使用得当,它将起作用。如果您想对非零有限值进行相等比较之外的操作,它将起作用。使用 IsNaN 是一个不错的选择。关键在于,你是在按照你不知道出处的价值观运作的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-23
  • 1970-01-01
相关资源
最近更新 更多