Invalid floating point operation delphi как исправить

Invalid floating point operation. Delphi Решение и ответ на вопрос 55345

Цитата
Сообщение от Puporev
Посмотреть сообщение

Код Delphi
1
2
b1:=Sqrt(DfX1); нахожу квадратный корень
b2:=Sqrt(DfX2);

Здесь при определенных значениях х, под корнем получается отрицательное число.
Если числа вводятся безконтрольно, то в этом случае можно выдавать предупреждение
Код Delphi
1
2
if DfX1<0 then showmessage(‘Подкоренное выражение меньше ноля’) else b1:=Sqrt(DfX1);

Да вы правы числа вводятся безконтрольно, вот вся программа

Delphi
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
function Func(x:real):real;
begin
Func:=-2*x+0.2*x*x;
end;
function Func1(x:real):real;
begin
Func1:=-2.4*x+0.2*x*x;
end;
function Df1(x:real):real;
begin
Df1:=-2+(0.4*x);
end;
function Df2(x:real):real;
begin
Df2:=-2.4+(0.4*x);
end;
 
procedure TForm1.Button1Click(Sender: TObject);
var
X1,X2:Real;
Fvek,Fvek2:Real;
L:Real;
B1,B2,B3:real;
DfX2,DfX1:Real;
Eps:Real;
A1,A2,x:real;
Sum:Real;
begin
L:=4;
X1:=StrToFloat(Edit1.Text);
X2:=StrToFloat(Edit2.Text);
Eps:=StrToFloat(Edit3.Text);
Fvek:=Func(X1);
Fvek2:=Func1(X2);
A1:=Fvek+Fvek2;
 repeat
  begin
   repeat
   A1:=Fvek+Fvek2;
    DfX1:=Df1(X1);
    DfX2:=Df2(X2);
    X1:=X1-L*DfX1;
    X2:=X2-L*DfX2;
    Fvek:=Func(X1);
    Fvek2:=Func1(X2);
   A2:= Fvek+Fvek2;
  until A1 > A2;
   DfX1:=Df1(X1);
   DfX2:=Df2(X2);
   b1:=Sqrt(DfX1);
   b2:=Sqrt(DfX2);
   sum:=b1+b2;
 end;
  until sum > Eps ;
 
//Label1.Caption:=FloatToStr();
end;
end.

т.е мне ненужно выводить сообщение о том что число под корнем отрицательное, оно должно считаться и сравниваться с Эпсилонтом в DfX2 значение все равно отрицательное и как его посчитать не знаю.
А решаю задачу многомерной оптимизации состоящую из 7 шагов
1- ввожу X1,X2;
2- нахожу их значения в функции F(X1,X2) у меня

Delphi
1
2
Fvek:=Func(X1);
Fvek2:=Func1(X2);

A1:=Fvek+Fvek2; получаю значение функции
3-нахожу производную для X1,X2

Delphi
1
2
DfX1:=Df1(X1);
DfX2:=Df2(X2);

4-нахожу новый X1,X2 подставл производную в формулу
X1:=X1-L*DfX1;
X2:=X2-L*DfX2;
5-нахожу их значения в функции F(X1,X2) уже с новыми X1,X2

Delphi
1
2
3
Fvek:=Func(X1);
 Fvek2:=Func1(X2);
 A2:= Fvek+Fvek2;

6-проверяю A1 и A2 если A1 >A2 тогда идем дальше если нет то цикл должен выполниться еще раз и уменьшить шаг т.е L:=L/2 это я в коде еще не реализовал
7—нахожу новые производные для X1,X2

Delphi
1
2
DfX1:=Df1(X1);
DfX2:=Df2(X2);

и пытаюсь впихнуть их в корень

Delphi
1
2
3
b1:=Sqrt(DfX1);
 b2:=Sqrt(DfX2);
 sum:=b1+b2;

проверяю условием
sum > Eps то выполняем еще иначе получаем долгожданный ответ.

I keep getting this error «Invalid Floating Point Operation».

I’m on 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;

I even checked on the cpu window, and it happens because its trying to load a floating point value from a pointer that is pointing at a null value.

It’s not the ReadMemory, because this little piece of code is on a while loop and it returns several valid values before running into this error.

What should I do?

Thanks in advance.

    msm.ru

    Нравится ресурс?

    Помоги проекту!

    Пожалуйста, выделяйте текст программы тегом [сode=pas] … [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.


    Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
    1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
    2. Как «свернуть» программу в трей.
    3. Как «скрыться» от Ctrl + Alt + Del (заблокировать их и т.п.)
    4. Как прочитать список файлов, поддиректорий в директории?
    5. Как запустить программу/файл?
    … (продолжение следует) …


    Вопросы, подробно описанные во встроенной справочной системе Delphi, не несут полезной тематической нагрузки, поэтому будут удаляться.
    Запрещается создавать темы с просьбой выполнить какую-то работу за автора темы. Форум является средством общения и общего поиска решения. Вашу работу за Вас никто выполнять не будет.


    Внимание
    Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
    Повторная попытка — 60 дней. Последующие попытки бан.
    Мат в разделе — бан на три месяца…

    >
    Ошибка при выполнении FloatToStr

    • Подписаться на тему
    • Сообщить другу
    • Скачать/распечатать тему



    Сообщ.
    #1

    ,
    07.09.12, 02:32

      Junior

      *

      Рейтинг (т): нет

      Имеем q:extended и s:string. При попытке выполнить s:=FloatToStr(q) вылетает «invalid floating point operation». При этом q имеет значение 0.0275. Ничего не понимаю. Пробовал менять значения, скажем на q:=0.1, ошибка все равно вылетает.


      RusSun



      Сообщ.
      #2

      ,
      07.09.12, 02:54

        Full Member

        ***

        Рейтинг (т): 6

        ExpandedWrap disabled

          procedure TForm1.Button1Click(Sender: TObject);

          var q:extended; s:string;

          begin

          q:=0.0275;

          s:=FloatToStr(q);

          Edit1.text:=s;

          end;

        попробуй помеять точку на запятую ?

        Добавлено 07.09.12, 02:55
        у меня правда и этот вариант работает)


        Sandy



        Сообщ.
        #3

        ,
        07.09.12, 03:42

          Junior

          *

          Рейтинг (т): нет

          Цитата RusSun @ 07.09.12, 02:54

          попробуй помеять точку на запятую ?

          Попробовал DecimalSeparator:=’,’ (и с точкой тоже) — не помогло.


          MBo



          Сообщ.
          #4

          ,
          07.09.12, 04:44

            Не исключено, что ошибка случилась раньше, и в стеке сопроцессора мусор. И стоит проверить перед операцией Get8087CW


            leo



            Сообщ.
            #5

            ,
            07.09.12, 05:52

              Да, видимо где-то раньше «затесалось» деление 0/0 или операция с неинициализированным вещ.числом (или неумелое использование встроенного asm’а для fpu-вычислений)


              Sandy



              Сообщ.
              #6

              ,
              07.09.12, 07:36

                Junior

                *

                Рейтинг (т): нет

                Покопался в SysUtils. Получилась примерно такая цепочка:
                FloatToStr -> SetString -> FloatToText -> FloatToDecimal
                Вот на FloatToDecimal и запинается. С asm’ом у меня не очень, поэтому просто тупо посмотрел на содержимое регистров CPU.

                Цитата MBo @ 07.09.12, 04:44

                И стоит проверить перед операцией Get8087CW

                Спасибо, почитаю хелп только.


                leo



                Сообщ.
                #7

                ,
                07.09.12, 08:00

                  Копаться в FloatToStr бесполезно, т.к. она работает нормально.
                  Но специфика fpu-операций x86 такова, что исключения генерятся не на самой инструкции, вызвавшей исключение, а на следующей за ней команде fpu. Поэтому во всех встроенных дельфийских функциях для работы с вещ.числами всегда вставляется пустая fpu-команда fwait, чтобы ошибка генерилась внутри самой функции, а не где-то после ее вызова. Поэтому возможные invalid operation, связанные с неверными аргументами Sqrt, Ln и т.п. должны возникать на самом вызове этих функций. Но когда ты, например, просто делишь два числа x/y, то может возникнуть ошибка деления 0/0, которая проявится не сразу, а на какой-то другой последующей операции с fpu (в твоем случае на вызове FloatToStr, хотя дело вовсе не вней). Подобный случай тут недавно обсуждался

                  Сообщение отредактировано: leo — 07.09.12, 08:02


                  Sandy



                  Сообщ.
                  #8

                  ,
                  07.09.12, 08:32

                    Junior

                    *

                    Рейтинг (т): нет

                    Цитата leo @ 07.09.12, 08:00

                    Копаться в FloatToStr бесполезно,

                    Да, так и получилось.

                    После прочтения одной статьи вставил Set8087CW(Get8087CW or $0100). На несколько проходов хватало. После чего опять появлялась ошибка.

                    Цитата MBo @ 07.09.12, 04:44

                    Не исключено, что ошибка случилась раньше, и в стеке сопроцессора мусор.

                    Точно. В куске кода, выдранном из старой программы, обнаружилась пара инструкций IF, использующих две объявленных, но не инициализированных переменных.

                    Всем спасибо!


                    Lumen



                    Сообщ.
                    #9

                    ,
                    07.09.12, 10:52

                      Я обычно FormatFloat использую для преобразования числа с плавающей точкой в строку. Заодно сразу и кол-во знаков после запятой указать можно.
                      Типа такого:

                      ExpandedWrap disabled

                        s:=FormatFloat(‘0.00’, q);


                      Dimonka



                      Сообщ.
                      #10

                      ,
                      07.09.12, 13:50

                        Обычно такие вещи случаются при использовании библиотек с MMX-ом. Например Graphics32. В таких библиотеках обычно пишут, как и после чего переключаться снова на FP.


                        antonn



                        Сообщ.
                        #11

                        ,
                        07.09.12, 16:23

                          Dimonka
                          это об?

                          ExpandedWrap disabled

                            asm

                              emms

                            end;

                          так обычно сама библиотека и следит


                          Sandy



                          Сообщ.
                          #12

                          ,
                          08.09.12, 02:15

                            Junior

                            *

                            Рейтинг (т): нет

                            Цитата Lumen @ 07.09.12, 10:52

                            Я обычно FormatFloat использую для преобразования числа с плавающей точкой в строку.

                            Хм… А на что можно использовать необычно? Это не сарказм, вопрос в целях повышения повышаемости.

                            Цитата Lumen @ 07.09.12, 10:52

                            ExpandedWrap disabled

                              s:=FormatFloat(‘0.00’, q);

                            Кажись наоборот, формат указывается после переменной.


                            Filka



                            Сообщ.
                            #13

                            ,
                            08.09.12, 02:44

                              Senior Member

                              ****

                              Рейтинг (т): 144

                              0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)

                              0 пользователей:

                              • Предыдущая тема
                              • Delphi: Общие вопросы
                              • Следующая тема

                              Рейтинг@Mail.ru

                              [ Script execution time: 0,0327 ]   [ 16 queries used ]   [ Generated: 9.02.23, 20:23 GMT ]  

                              Понравилась статья? Поделить с друзьями:
                            • Invalid file version plants vs zombies как исправить windows 10
                            • Invalid file bad magic number exec format error
                            • Internal system error in https inspection error code 2
                            • Internal system error in https inspection due to categorization service timeout
                            • Internal storage low как исправить