2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 помогите решить проблему
Сообщение09.11.2009, 00:30 
почему функция fmod, возвращающая остаток от деления в приведенном ниже цикле может работать неправильно, тоесть чаще всего выводится t равное нулю или еще какая-нибудь ерунда
код: [ скачать ] [ спрятать ]
Используется синтаксис C
while ((z<=zmax)&(t<=tout))                    
        {      
                m=4/3*pi*pow(r,3)*p_H2;
                v=v+(g*(p_a/p_H2/(1+M/m)-1)-(9/2*n*v/pow(r,2)/p_H2)/(1+M/m))*dt;
                z=z+v*dt;        
                        //printf("%lf\n",fmod(t,t_out));
                        if (fmod(t,t_out)==0)
                        {
                                printf("t=%lf   v=%lf  z=%lf\n",t,v,z);
                        }    
                P=P-p_a*g*v*dt;
                T=T-gamma*v*dt;
                p_a=P*mu_a/R/T;
                p_H2=P*mu_H2/R/T;
                r=r0*pow((P0*T/P/T0),1/3);             
                t=t+dt;            
        }

Без цикла функция работает правильно, если вставить закоментированную строчку то выводимая в ней величина меняется от 0,01 до t_out включительно!(остаток равен делителю).

 
 
 
 Re: помогите решить проблему
Сообщение09.11.2009, 00:46 
А чего Вы хотите добиться?
fmod возвращает double, поэтому условие
Код:
if (fmod(t,t_out)==0)
будет выполняться очень-очень редко (фактически, только в случаях, когда t == 0).
Нельзя сравнивать числа типа double на равенство - такая проверка почти никогда не сработает; вместо этого надо сравнивать абсолютное значение разности с каким-нибудь маленьких числом, например, так:
Код:
if (fabs(fmod(t,t_out)) < 1e-6)


-- Пн ноя 09, 2009 01:01:16 --

У Вас что, воздушный шар взлетает? :)

 
 
 
 Re: помогите решить проблему
Сообщение09.11.2009, 01:29 
Вы сравниваете числа с плавающей запятой на точное равенство, а это часто приводит к неправильному результату, т.к. такие числа по определению не точны.
Некоторые числа представимы точно, например, ноль, так что неудивительно, что как раз ноль вы и видите чаще.
Насколько я понял вам надо, чтобы t было кратно t_out.
Если допустить неточность eps, то такая проверка будет выглядеть так:
Код:
if ( fabs(fmod(t, t_out)) <= eps || fabs(fmod(t, t_out)) >= 1-eps )

Понятно, что лучше вычислить выражение fabs(fmod(t, t_out)) только раз.

 
 
 
 Re: помогите решить проблему
Сообщение09.11.2009, 03:20 
Аватара пользователя
Можно сравнивать так (на равенство):
Код:
if((a>=x)&&(x>=a));

 
 
 
 Re: помогите решить проблему
Сообщение09.11.2009, 11:41 
Спасибо, стало понятно.
Цитата:
У Вас что, воздушный шар взлетает? :)

Да, можно сказать что шар :)

 
 
 [ Сообщений: 5 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group