Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 23.01.2015, 21:01   #1
Lamia
Пользователь
 
Регистрация: 24.08.2014
Сообщений: 15
По умолчанию C++ Builder "Invalid Floating Point Operation"

В функции, приведенной ниже, при сдвиге точки зрения (PVw) в определенный момент возникает ошибка "Invalid Floating Point Operation". После ряда различных манипуляций пришел к выводу, что скорее всего дело в a2 и последующем его использовании (правда еще не понял, где именно, хотя строк там не много). Ошибка выдается, как правило, когда a2 = -4,20345940998619E17.
Иного значения при ошибке пока не замечал.
В чем может быть проблема и как ее устранить?
Код:
float PVw[6] = { 0.5, 0.5, 3.0,
                        0.0, 0.0, 0.0 };
int Stocks2()
{
  POINT MPos;
  float aY,aZ;
  int mid_x, mid_y;
  float S0,S1,S2,S3,a1,a2,a3;
  POINT cl;

  aY = 0.0;
  aZ = 0.0;
 cl = Form1->Panel1->ClientOrigin;

 mid_x = ( Form1->Panel1->ClientWidth >>1 ) + cl.x;
 mid_y = ( Form1->Panel1->ClientHeight >>1 ) + cl.y;
  GetCursorPos(&MPos); 
  if ( (MPos.x == mid_x) && (MPos.y == mid_y)  )
  {
        return 0;
  }
  SetCursorPos(mid_x, mid_y);
  aY = (mid_x - MPos.x);
  aZ = (mid_y - MPos.y);
  
  S1 = floor( (PVw[2] - PVw[5])*100000 ) / 100000; 
//попытка округлить, если без этого, ошибка вылетает чаще
  //S1 = PVw[2] - PVw[5];
  S2 = floor( (PVw[0] - PVw[3])*100000 ) / 100000;
  //S2 = PVw[0] - PVw[3];
  S3 = floor( (PVw[1] - PVw[4])*100000 ) / 100000;
  //S3 = PVw[1] - PVw[4];
  S0 = sqrt( fabs( pow(PVw[1] - PVw[4],2) ) +
              fabs(  pow(PVw[0] - PVw[3],2) ) +
              fabs ( pow(PVw[2] - PVw[5],2) ) );
//была версия, что отрицательное число под корнем, хотя по идее pow(x,2) должно вернуть >0
  S0 = floor( S0*100000 ) / 100000;
  a1 = asin( S3/S0 );
  a1 = floor( a1*100000 ) / 100000;

  if ( ( a1 < M_PI_2 ) && ( a1 > (0-M_PI_2)) )
  {
    if ( S0*cosl(a1) != 0 )
    {
        if ( ( S1/(S0*cosl(a1)) > -1 ) && ( S1/(S0*cosl(a1)) < 1 ) )
        {
                a2 = acosl( S1/(S0*cosl(a1)) ) ;
        }
    }
  }
  else
  {
      if ( (S0*cosl(a1+M_PI/180)) != 0 )
      {
        if ( ( S1/(S0*cosl(a1+M_PI/180)) > -1 ) &&
                ( S1/(S0*cosl(a1+M_PI/180)) < 1 ) )
        {
                a2 = acosl( S1/(S0*cosl(a1+M_PI/180)) ) ;
        }
      }
  }

  a3 = a1;
  a1 = a1 - aZ*50*M_PI/180/1000;
  if (a1 >= (M_PI_2) ) { a1 = a3; };
  if ( a1 <= (0-M_PI_2) ) { a1 = a3; };

  a2 = floor( a2*100000 ) / 100000;

  if (S2 < 0)
  {
    a2 = 0 - a2 + aY*50*M_PI/180/1000 ;
  }
  else
  {
    a2 = a2 + aY*50*M_PI/180/1000;
  }

  a2 = floor( a2*100000 ) / 100000; 
//снова округление, предполагаю, что ошибка из-за этой переменной

  S1 = S0*cos(a1)*cos(a2);
  S2 = S0*cos(a1)*sin(a2);
  S3 = S0*sin(a1);

  PVw[2] = PVw[5] + S1;
  PVw[0] = PVw[3] + S2;
  PVw[1] = PVw[4] + S3;

  return 1;
}
Lamia вне форума Ответить с цитированием
Старый 23.01.2015, 21:22   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Ошибка выдается, как правило, когда a2 = -4,20345940998619E17.
-4 в 17-й степени... Ниче так число...
Слишком большое.
Что программа делает? Что вычисляет? Может ошибка в формулах?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 23.01.2015, 21:38   #3
Lamia
Пользователь
 
Регистрация: 24.08.2014
Сообщений: 15
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
-4 в 17-й степени... Ниче так число...
Слишком большое.
Что программа делает? Что вычисляет? Может ошибка в формулах?
Расчет параметров Стокса. Точнее координат точки на поверхности какой-то сферы. Все вычисления приведены в этой функции.
а2 это плоский угол в радианах. Угол к оси Z в плоскости XZ. Формулы наверняка верны, ибо координаты вычисляются верно.

кажется решил проблему, после вычисления а2 вставил проверку на ее значение
Код:
if ( ( a2 > M_PI*2 ) ||  ( a2 < M_PI*(-2)) ) 
  {
        a2 = M_PI;
  }
Во всяком случае, пока что более не вылетает в этом месте.
И да, ошибка выпадала в основном именно в 180 градусах к оси Z. Точнее когда z=-число, а x=0.

Однако это не совсем решение. Для этой позиции все хорошо, но то же число и та же ошибка вылетает и когда z>0, если убрать те округления, что вставлял ранее.

Последний раз редактировалось Stilet; 23.01.2015 в 22:20.
Lamia вне форума Ответить с цитированием
Старый 23.01.2015, 22:04   #4
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

А что это за угол такой 4^17 В каких единицах измерения?

Цитата:
после вычисления а2 вставил проверку на ее значение
вот-вот, и я о том же. Только навряд ли так. Его наверно нужно в интервале [-2пи;2пи] сделать, а не к пи приравнять. Возможно и не прав
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 23.01.2015 в 22:11.
Аватар вне форума Ответить с цитированием
Старый 23.01.2015, 22:07   #5
Lamia
Пользователь
 
Регистрация: 24.08.2014
Сообщений: 15
По умолчанию

Цитата:
Сообщение от Аватар Посмотреть сообщение
А что это за угол такой 4^17 В каких единицах измерения?

вот-вот, и я о том же
в радианах . Его acosl выдает при приближении координат к тем, что я описал выше.

Цитата:
Сообщение от Аватар Посмотреть сообщение
А что это за угол такой 4^17 В каких единицах измерения?

вот-вот, и я о том же. Только навряд ли так. Его наверно нужно в интервале [-2пи;2пи] сделать, а не к пи приравнять. Возможно и не прав
В данном случае именно Pi нужно, потому что вылетает за ним. Но! При проверке на Pi с отрицательным S1 все в порядке, а вот в положительной области ошибка остается все равно.

Код:
if ( ( a2 < M_PI*(-2) ) && ( S1 > 0 )  )
  {
      a2 = 0; //вот тут то бишь
  }
  else
  if  ( ( a2 < M_PI*(-2) ) && ( S1 < 0 ) )
  {
        a2 = M_PI;
  }
меньше надо было. Ошибки более нет, но зато вычисления становятся после этой правки не корректными, координаты прыгают вокруг этой области.
Ох, Боги, минус забыл.
Кажется теперь все хорошо.

Последний раз редактировалось Stilet; 23.01.2015 в 22:23.
Lamia вне форума Ответить с цитированием
Старый 23.01.2015, 22:24   #6
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
Расчет параметров Стокса
И чего я математику в универе не учил?... Надо было пива меньше пить, и уроки не пропускать.
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 23.01.2015, 22:24   #7
Lamia
Пользователь
 
Регистрация: 24.08.2014
Сообщений: 15
По умолчанию

В общем эта проверка решила проблему, спасибо всем.
Код:
if ( ( a2 < M_PI*(-2) ) && ( S1 > 0 )  )
  {
      a2 = 0; 
  }
  else
  if  ( ( a2 < M_PI*(-2) ) && ( S1 < 0 ) )
  {
        a2 = M_PI;
  }
Цитата:
Сообщение от Stilet Посмотреть сообщение
И чего я математику в универе не учил?... Надо было пива меньше пить, и уроки не пропускать.
На вышке этого кажется не было. Узнал о них после изучения поляризации света.

Последний раз редактировалось Stilet; 23.01.2015 в 22:43.
Lamia вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
invalid floating point operation MaxiRush Помощь студентам 2 03.11.2013 15:08
Ошибка - "invalid floating point operation" Hemou' Помощь студентам 1 21.12.2012 17:04
Ошибка "Invalid floating point operation" в программе на Delphi Matrix6993 Помощь студентам 1 24.05.2012 23:36
Invalid floating point operation _SatanA_ Общие вопросы Delphi 11 01.02.2012 11:26
invalid floating point operation mosq Общие вопросы Delphi 7 01.11.2009 13:28