На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
! ПРАВИЛА РАЗДЕЛА · FAQ раздела Delphi · Книги по Delphi
Пожалуйста, выделяйте текст программы тегом [сode=pas] ... [/сode]. Для этого используйте кнопку [code=pas] в форме ответа или комбобокс, если нужно вставить код на языке, отличном от Дельфи/Паскаля.
Следующие вопросы задаются очень часто, подробно разобраны в FAQ и, поэтому, будут безжалостно удаляться:
1. Преобразовать переменную типа String в тип PChar (PAnsiChar)
2. Как "свернуть" программу в трей.
3. Как "скрыться" от Ctrl + Alt + Del (заблокировать их и т.п.)
4. Как прочитать список файлов, поддиректорий в директории?
5. Как запустить программу/файл?
... (продолжение следует) ...

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


Внимание
Попытки открытия обсуждений реализации вредоносного ПО, включая различные интерпретации спам-ботов, наказывается предупреждением на 30 дней.
Повторная попытка - 60 дней. Последующие попытки бан.
Мат в разделе - бан на три месяца...
Модераторы: jack128, D[u]fa, Shaggy, Rouse_
  
> floating point invalid operation , Графика, перемещение объекта
    Имитация движения объекта (точка радиусом 3 пиксела) производится следующим образом: пересчитываются его координаты, на месте его текущего положения перерисовывается фон, сохраненный ранее в его свойстве Bmp, объект отрисовывается в точке с новыми координатами.
    Однако, при этом иногда возникает ошибка: floating point invalid operation вот в этом месте программы:

    Form1.PaintBox1.Canvas.Draw(X-3, Y-3, Bmp); //восстанавливаем фон, извлекая его из свойства Bmp и помещая в текущее месторасположение объекта

    С чем может быть связана данная ошибка (повторюсь, что возникает она не всегда)?
      Необходимо отметить, что количество объектов, которые отрисовываются, увеличивается за счет создания все новых объектов в цикле. И кроме вышеуказанной ошибки возникает также и другая (а именно project raised exception class EOutOfResources with message 'Out of system resources') в момент отрисовки объекта:

      Form1.PaintBox1.Canvas.Pen.Color := clRed;
      Form1.PaintBox1.Canvas.Brush.Color: =clRed;
      Form1.PaintBox1.Canvas.Ellipse(X-3, Y-3, X+3, Y+3);
        Ошибка в другом месте
          Цитата leo @
          Ошибка в другом месте

          Как же его, это место выловить, если выскакивают эти ошибки всегда именно в этих дух местах программы?
            Цитата dimavit @
            Как же его, это место выловить

            Практический совет - учитесь пользоваться отладчиком. И используйте при пошаговом выполнении не только кнопку F8, но и кнопку F7.
            Теоретические советы вы найдёте в этой статье гуру "Обработка ошибок". Статья довольно большая по объёму, но очень полезная. Советую не только прочитать её вдумчиво, но и сохранить ссылку на неё. Ибо это явно не последняя ошибка в ваших программах.
              Цитата dimavit @
              Как же его, это место выловить, если выскакивают эти ошибки всегда именно в этих дух местах программы?

              Привести больше кода. В частности, ошибка EOutOfResources может возникать как из-за того, что у тебя действительно используется слишком много объектов GDI, а может из-за того, что просто где-то не освобождаются временные объекты, например TBitmap. А ошибка ес-но возникает при создании очередного нового объекта (в данном сл. Pen и Brush).
              Что казается fp-исключений, то они в x87 вообще генерятся не на самой команде, вызвавшей исключение, а на следующей fp-команде процессора. У тебя вообще вещественные вычисления используются?
              Сообщение отредактировано: leo -
                Цитата northener @
                Цитата dimavit @
                Как же его, это место выловить

                Практический совет - учитесь пользоваться отладчиком. И используйте при пошаговом выполнении не только кнопку F8, но и кнопку F7.
                Теоретические советы вы найдёте в этой статье гуру "Обработка ошибок". Статья довольно большая по объёму, но очень полезная. Советую не только прочитать её вдумчиво, но и сохранить ссылку на неё. Ибо это явно не последняя ошибка в ваших программах.

                Спасибо за ссылку. Навыки отладки, это конечно совершенно необходимо и их явно не хватает. Кстати, не могли бы Вы в этом смысле подсказать, что может означать ошибка, которая указывается в Call Stack: :0040493b @ROUND +$3? Она то и является причиной первой проблемы. А вторую вроде бы побороть удалось.
                  Цитата dimavit @
                  что может означать ошибка, которая указывается в Call Stack: :0040493b @ROUND +$3?

                  То и означает, что при вызове Round округленное вещ.значение не умещается в целый тип и возникает ошибка: floating point invalid operation
                  Сообщение отредактировано: leo -
                    Цитата leo @
                    Цитата dimavit @
                    Как же его, это место выловить, если выскакивают эти ошибки всегда именно в этих дух местах программы?

                    Привести больше кода.

                    Код довольно длинный, но логика такая:
                    1. Имеется динамический массив объектов среди свойств которых находятся их координаты (x и y) и снимок поверхности канвы, перекрываемой данным объектом в текущий момент, и помещаемый туда непосредственно перед самим перемещением в это место.
                    2. Вначале имеется 2 объекта, но при их столкновении появляются новые объекты, который помещаются в существующий массив и случайным образом задаются их координаты. Таким образом происходит как бы цепная реакция с лавинообразным нарастанием длины динамического массива.
                    3. Движение происходит в цикле, который сканирует расстояние от первого элемента массива до остальных, потом от второго до остальных и т.д. Расстояние округляется (единственное место где используются нецелые числа), оценивается и, в зависимости от этой оценки, происходят разные события.
                    4. Визуально отображение движения частиц на экране происходит путем вычерчивания круга в месте нового положения частицы, а на месте ее старого положения канва восстанавливается путем наложения снимка, хранящегося в свойствах объекта.
                    5. Так вот, при нарастании количества частиц и длины массива, в определенный момент, всегда в одном и том же месте программы, происходит сбой при попытке отрисовки нового положения объекта (Form1.PaintBox1.Canvas.Draw(X-3, Y-3, Bmp)).
                    6. Можно было бы предположить, что в один и тот же момент разные объекты пытаются обратиться к одному и тому же месту на канве (кто-то читает, кто-то записывает, или одновременно читают, либо записывают), но ведь, насколько я знаю, в случае существования в программе всего одного потока, следующая операция не может начаться до окончания предыдущей. Кроме того, если закомментировать эту строку //Form1.PaintBox1.Canvas.Draw(X-3, Y-3, Bmp) (при этом движение объекта будет оставлять след, поскольку не восстанавливается канва) то остановка происходит ровно на следующей за ней сроке кода if Direction[0] then SetX(Random(Step)*Speed), отвечающей уже за определение направления движения. Код ошибки тот же - floating point invalid operation.
                    7. Очевидно, что проблема связана с лавинообразным нарастанием количества объектов, однако проявиться она может и при 4, и при 850 элементах, существующих в массиве.

                    Я понимаю, что природа ошибки может быть самой разной, но подскажите хотя бы в каком направлении необходимо копать. Спасибо.
                      Разделяй и властвуй )

                      ищи отсекая не нужное {} или (* *) или //

                      Ну и хорошо выложить, то что выдаёт ошибку)

                      Чтобы не напрягать телепатические способности ;)
                        Цитата dimavit @
                        Я понимаю, что природа ошибки может быть самой разной, но подскажите хотя бы в каком направлении необходимо копать.

                        "Природа" м.б. разной, но источником fp-invalid-op являются
                        1) вызов sqrt(x) при x < 0
                        2) i:=round(x) или trunc(x), при x > High(i) или x < Low(i)
                        3) экзотические ситуации неправильной работы со стеком FPU (возможны только при собственных косяках при использовании встроенного асма)
                        Поэтому, если у тебя ф-я round вызывается в одном месте, то вставь перед ней проверку вещ.числа на допустимый диапазон:
                        ExpandedWrap disabled
                             d:=...; //расчет вещественного расстояния
                             if (d >= Low(di) and (d < High(di)) then
                               di:=round(d)
                             else
                               di:=0; //<-- поставь брикпойнт на эту строку

                        Если брик сработает, то смотри чему равно d и другие переменные, из которых оно высчитывалось

                        Добавлено
                        PS: Можно конечно просто поставить условный брик на строку с round, но работать это будет о-о-очень долго
                          Кстати EInvalidOp также генерируется при вещественном делении 0/0 - скорее всего это и есть источник ошибки при попытке вычисления нулевого расстояния между совпадающими точками. В этом случае ошибка как раз генерируется не на самой команде деления, а на следующей fpu-команде. Поэтому, если затем вызывается Round, то ошибка возникает на первой же команде fistp по адресу @ROUND+$3, а не на второй fwait @ROUND+$6, как было бы в случае невозможности преобразовать вещ.число в Int64
                            Цитата leo @
                            Кстати EInvalidOp также генерируется при вещественном делении 0/0 - скорее всего это и есть источник ошибки

                            Спасибо, огромное. Именно так оно и было. Одной проблемой стало меньше.
                            1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                            0 пользователей:


                            Рейтинг@Mail.ru
                            [ Script execution time: 0,0425 ]   [ 15 queries used ]   [ Generated: 18.07.25, 12:24 GMT ]