Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Floating point overflow


Автор: trinitr0 24.9.2014, 16:22
В коде построения графика по формуле расчёта методом конечных разностей
(метод решёток):

Код

double dT[8];
     float T[8];

     int i;
     int m = 8;

     float dtau = 0.1;
     float lx = 0.14;
     float a = 0.0001; 
     //float dx = 0.02;  
     float dx = lx/(m-1);
     long int tt;

     for (int i=0; i<m; i++)
     {
        dT[i]=0;
        T[i]=0;
     }


     for (tt=0; tt<=500; tt++)
     {
         T[0] = 100;

                for (int i=0; i<=m; i++)
                {
                      T[7] = 0;

                         for (int i=1; i<m-1; i++)
                         {
                           dT[i] = a*dtau*((T[i-1]-2*T[i]+T[i+1])/(dx*dx))+T[i];
                           T[i] = T[i]+dT[i];
                         }

                        if (tt%100 == 0)
                           Series1 -> AddXY(tt*dtau, T[2]);

                }
      }


при нажатии появляется сообщение о переполнении (Floating point overflow), 
и указание на строчку с формулой dT[i] = a*dtau*((T[i-1]-2*T[i]+T[i+1])/(dx*dx))+T[i];

Но если в строчке 29 задать i от 3 (i=3...), то рисуется просто прямая линия...

В формуле, вроде, ошибок нет... Помогите пожалуйста!

Автор: tzirechnoy 24.9.2014, 19:31
Цитата
Код

       for (int i=0; i<=m; i++)
         ...
         for (int i=1; i<m-1; i++)


Неудивительно.

Автор: trinitr0 25.9.2014, 09:07
Поправил так:

Код

double dT[8];
     float T[8];
     int i;
     int m = 8;
     float dtau = 0.1;
     float lx = 0.14;
     float a = 0.0001; 
     //float dx = 0.02;  
     float dx = lx/(m-1);
     long int tt;
     for (int i=0; i<m; i++)
     {
        dT[i]=0;
        T[i]=0;
     }
     
      for (tt=0; tt<=500; tt++)
     {
         T[0] = 100;
               
                      T[7] = 0;
                         for (int i=1; i<m-1; i++)
                         {
                           dT[i] = a*dtau*((T[i-1]-2*T[i]+T[i+1])/(dx*dx))+T[i];
                           T[i] = T[i]+dT[i];
                         }
                        if (tt%100 == 0)
                           Series1 -> AddXY(tt*dtau, T[2]);
       }
  


Но всё равно при нажатии рисуется прямая просто линия, вместо графика... 

Автор: xvr 25.9.2014, 13:19
Цикл вы зря выкинули, верните обратно, но сделайте ему отдельную переменную для цикла.
Замените все float на double, и исправьте индекс T в AddXY (там должно быть T[1])

Автор: trinitr0 25.9.2014, 13:29
Спасибо, сейчас попробую...

Добавлено через 5 минут и 11 секунд
Написал теперь так:

Код

{
     double dT[8];
     double T[8];

     int i;
     int m = 8;

     float dtau = 0.1;
     float lx = 0.14;
     float a = 0.0001;
     //float dx = 0.02;
     float dx = lx/(m-1);
     int tt;

     int x;

     for (int i=0; i<m; i++)
     {
        T[i]=0;
        dT[i]=0;
     }


     for (int tt=1; tt<=500; tt++)
     {
         T[0] = 100;

                for (int j=0; j<=m; j++)
                {
                      T[7] = 0;

                         for (int i=2; i<m-1; i++)
                         {
                           dT[i] = a*dtau*((T[i-1]-2*T[i]+T[i+1])/(dx*dx))+T[i];
                           T[i] = T[i]+dT[i];


                              if (tt%100 == 0)
                                Series1 -> AddXY(tt*dtau, T[1]);
                         }
                }
      }
  }


Но всё равно просто прямая линия и нули... 

Автор: xvr 25.9.2014, 13:46
  • У вас if (tt%100 == 0) оказался внутри цикла (в строке 32), а должен быть снаружи
  • Поставьте double везде, где был float, а не только в массивах
  • Цикл в строке 32 должен начинаться с 1, а не с 2


Автор: trinitr0 25.9.2014, 14:53
Спасибо!!! Решено!   smile 


Применив ваши советы, ещё попотев пришёл к такому рабочему коду:

Код

void __fastcall TForm1::Button1Click(TObject *Sender)
{
     const int m = 8;
     double dT[m],
             T[m],

             dtau = 0.1,
             lx   = 0.14,
             a    = 0.0001;

     double dx    = lx/(m-1);

     for (int i=0; i<m; i++){
        T[i]=dT[i]=0;
     }

     for (int tt=1; tt<=500; tt++){
         T[0] = 100;
         T[7] = 0;
                      for (int i=1; i<m-1; i++){

                          dT[i] = a*dtau*((T[i-1]-2*T[i]+T[i+1])/(dx*dx))+T[i];
                          T[i] = T[i]+dT[i];

                      }

                    if (tt%100 == 0)
                       Series1 -> AddXY(tt*dtau, T[2]);
                      
                }
      }
  }


Автор: xvr 26.9.2014, 09:30
Он может и рабочий, но исходному коду на Delphi он не соотвествует.
Повторюсь -

Цитата(xvr @  25.9.2014,  13:19 Найти цитируемый пост)
Цикл вы зря выкинули, верните обратно, но сделайте ему отдельную переменную для цикла.
Исправьте индекс T в AddXY (там должно быть T[1])


Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)