2010-04-26 5 views
4
#include<stdio.h> 
#include<math.h> 

int main() 
{ 
    FILE *fp; 
    fp=fopen("output","w"); 
    float t,y=0,x=0,e=5,f=1,w=1; 
    for (t=0;t<10;t=t+0.01) 
    { 
     if(y==inf && y== nan) 
      break; 
     fprintf(fp,"%lf\t%lf\n",y,x); 
     y = y + ((e*(1 - x*x)*y) - x + f*cos(w*t))*t; 
     x = x + y*t; 
    } 
    return 0; 
} 

Почему дубль дает бесконечные значения и значения NAN?исключение с плавающей запятой в коде C!

+1

Хотя это был помечен C++, не так ли C99? Я не вижу ни одной используемой функции C++ ... – Yacoby

+0

, но будет ли это иметь значение для вывода? – Hick

+0

Не могли бы вы использовать более значимые имена переменных? Нам будет полезно лучше понять ваш код. –

ответ

4

O thers указали, что у вас проблемы с наном/инф, что верно, но вот как исправить ваш код, чтобы дать вам результаты, которые, как я считаю, вы ищете.

Поскольку никто другой не указал на это (я заметил), вы пытаетесь решить систему дифференциальных уравнений, используя Euler method.В сочетании дифференциальных уравнений, которые вы решаете являются:

dy/dt = e*(1 - x * x) * y - x + f * cos(w * t) 

dx/dt = y 

Однако, ваше решение является дефектным, который дает огромную численную нестабильность (и неправильный ответ). Эти две линии:

y = y + ((e*(1 - x*x)*y) - x + f*cos(w*t))*t; 
    x = x + y*t; 

должно быть:

y = y + ((e*(1 - x*x)*y) - x + f*cos(w*t))*.01; 
    x = x + y*.01; 

где я изменил т к вашей дельта т (шаг времени), потому что это то, что метод Эйлера требует. Я бы сделал новую переменную под названием delt или что-то в этом роде, чтобы вы могли легко изменить временной шаг. Теперь решение красиво стабилизируется, и график x vs. t и y vs. t дает некоторые очень приятные сюжеты. Я бы опубликовал их, но у меня есть ощущение, что это может быть домашнее задание.

Кроме того, если с помощью разных уравнений вам требуется больше стабильности, вы можете использовать меньшие временные шаги или некоторые более совершенные числовые методы ODE, такие как Runge-Kutta или неявные методы.

3

Возможно, условное утверждение должно быть, если (y == inf || y == nan)? y не может одновременно быть одновременно inf и NaN.

+0

no Я хочу знать, почему этот код дает inf или NAN в качестве вывода в первом случае? – Hick

+0

'y == nan' всегда false, для любого значения' y' (даже 'nan'). –

1

Поскольку перерыв никогда не произойдет, как указано в томе, и вы никогда не закрываете файл, данные не записываются, а затем все это ломается, когда действительно происходит исключение. Попробуйте очистить данные до файла в цикле for.

+0

с помощью fflush? – Hick

+1

Я не уверен в том, какой метод вы должны назвать. Почему вы не используете потоковое вещание? http://www.cplusplus.com/reference/iostream/ostream/flush/ – flayn

6

По сравнению с inf или nan осуществляется через isnan() и isinf() функции, не так.
%lf предназначенный для double, а не float.

И, ради бога, fclose() ваш файл! (первые X-строки представляют собой некоторые значащие числа.)

+0

@AndreyT: фактически,% lf для double с scanf. С printf% f преобразует double, а% lf вообще не определяется. Большинство реализаций, похоже, согласны с тем, чтобы обеспечить некоторую степень симметрии scanf, но они не обязательны (и, возможно, не должны). –

+0

Бог, если она существует, не волнует, закрывает ли он свой файл или нет. Но я чувствую вашу боль @Yossarian. –

+0

@ Джерри Коффин: Вы правы. Фактически, он определен (по крайней мере на C99), поскольку не влияет на спецификатор '% f', т. Е.'% Lf' эквивалентен '% f'. C89/90 действительно говорит, что поведение не определено. – AnT

8

Ваш расчет взрывается. Просто посмотрите на значения, напечатанные для x и y, и вы увидите, что они начинают становиться очень большими, а затем превращать информацию inf. Поскольку ваше условное не так, вы завершаете использование inf в вычислении, которое превращается в nan.

3

Помните также, что каждое сравнение с использованием NaN возвращает false независимо от того, какой оператор вы используете (<, < =, и т. Д.) И с чем вы сравниваете его.

0

Я подключил ваши уравнения к Excel и когда t получает значение 0.39 x и y 2E + 270 и 5.2E + 270 в активном режиме. После этого они слишком велики для обработки Excel. Вот след от других значений, если вы заинтересованы (паршивая форматирование, я знаю):

 
t x  y 
0.00 0  0 
0.01 9.9995E-05 0.0099995 
0.02 0.000719864 0.03099345 
0.03 0.002688085 0.065607372 
0.04 0.007431658 0.118589309 
0.05 0.017321769 0.197802239 
0.06 0.036281294 0.315992075 
0.07 0.070850729 0.493849065 
0.08 0.132072044 0.765266446 
0.09 0.238828626 1.186184238 
0.10 0.423641428 1.848128022 
0.11 0.741634646 2.89084744 
0.12 1.277397835 4.464693237 
0.13 2.107123319 6.382503724 
0.14 3.048840735 6.726552977 
0.15 3.361369798 2.083527082 
0.16 3.297988472 -0.396133288 
0.17 3.231095608 -0.393487431 
0.18 3.156811159 -0.412691383 
0.19 3.07386543 -0.436556472 
0.20 2.980485636 -0.466898968 
0.21 2.874086586 -0.506662146 
0.22 2.750700903 -0.56084401 
0.23 2.603841953 -0.638517177 
0.24 2.42203123 -0.757544679 
0.25 2.18283838 -0.9567714 
0.26 1.836632623 -1.331560601 
0.27 1.255566799 -2.152095647 
0.28 0.052253914 -4.297546016 
0.29 -2.923971917 -10.2628477 
0.30 -2.375067218 1.82968233 
0.31 -1.600801299 2.497631996 
0.32 0.082957072 5.261744912 
0.33 4.774399642 14.21649263 
0.34 -20.07952886 -73.09978971 
0.35 3522.569432 10121.85417 
0.36 -16277355468 -45214886085 
0.37 1.64003E+30 4.43252E+30 
0.38 -1.72156E+90 -4.53043E+90 
0.39 2.0423E+270 5.2366E+270 
0.40 #NUM!  #NUM! 

Так что я думаю, вопрос в том, что он этот код должен вычислить?

0

Среди других проблем, с которыми другие обратились, условный разрыв никогда не будет запущен. y == nan неверно для каждый значение y, включая NaN, поэтому состояние равно (y == inf && false), что, конечно, false.

Если вы хотите разорвать, когда y является inf или nan, вы должны использовать:

if (isinf(y) || isnan(y)) break; 

Или, если вы хотите использовать сравнение вместо:

if (fabs(y) == inf || y != y) break; 

(The FABS включены, потому что вы, предположительно, также хотите сломать, если y - -inf.)

Смежные вопросы