2015-11-12 3 views
0

Я занимаюсь некоторыми моделями болезней на C/C++ и хотел бы получить больше точности из него. Я думал об использовании длинных удвоений, для 80-битной точности (я использую cygwin`s GCC 4.8.3), но после расчета с этим я получаю значение «nan» (не число). Вот код, с которым я работаю. Все переменные длинны.Длинный двойной реселлинг до 0 после присвоения

#include <cstdlib> 
#include <iostream> 
#include <cstdio> 
#include <ctime> 
#include <random> 
#include <omp.h> 
#include <cfloat> 



using namespace std; 

int 
main (int argc, char** argv) 
{ 

    long double S, E, I, R, V, dS, dE, dI, dR, dV; 
    long double a, b, g, t, c, d, e, f; 
    long double dt = .005, tmax = 365; 

    S = 318000000; 
    I = 1; 
    E = 0; 
    R = 0; 
    V = 0; 

    FILE* F; 

    F = fopen ("valoresSIR1.txt", "w+"); 
    //fprintf (F, "Tempo, Susceptivel, Incubado, Infectado, Recuperado, Vacinado\n"); 

    a = 0.000005; 
    b = 0.01; 
    c = 0.05; 
    d = 0.000034; 
    e = 0.00000; 
    f = 0.0; 
    g = 0.000000; 
    t = 0.0000; 

    //printf("%Lg", a); exit(0); 
    for (long double i = 0; i < tmax; i += dt) 
    { 
     dS = (- a * I * S - g + t * R + d * (S + E + R + V) - f * S) * dt; 
     dE = (a * I * S - c * E - g) * dt; 
     dI = (c * E - g - e * I - b * I) * dt; 
     dR = (b * I - g - t * R) * dt; 
     dV = (f * S - g) * dt; 


     S += dS; 
     E += dE; 
     I += dI; 
     R += dR; 
     V += dV; 

     //printf ("%Lg, %Lg, %Lg, %Lg, %Lg, %Lg\n", S, E, I, R, V); 
     std::cout.precision (50); 
     std::cout << S << std::endl; 
     exit (0); 
     fprintf (F, "%Lg, %Lg, %Lg, %Lg, %Lg, %Lg\n", i, S, E, I, R, V); 
     switch ((int) i) 
     { 
      case 0: std::cout << i << endl; 
       break; 
      case 100: std::cout << i << endl; 
       break; 
      case 200: std::cout << i << endl; 
       break; 
      case 300: std::cout << i << endl; 
       break; 
      case 4000: std::cout << i << endl; 
       break; 
      case 5000: std::cout << i << endl; 
       break; 
      case 6000: std::cout << i << endl; 
       break; 
      case 7000: std::cout << i << endl; 
       break; 

     } 

    } 

    fclose (F); 

    return 0; 
} 

Ожидаемые значения для вывода: http://pastebin.com/mJqkSVUf

+0

Каковы значения 'tmax' и' dt'? – nnn

+1

Я могу задать много глупых вопросов, таких как «Инициализируется ли S?» или вы можете предоставить компилируемую версию этого кода. –

+1

Этот код далеко не полный и компилируемый. Что вы ожидаете от этого? –

ответ

4

Расчет dS = (- a * I * S - g + t * R + d * (S + E + R + V) - f * S) * dt; использует неинициализированную переменную V. Это вызывает неопределенное поведение.

Когда происходит неопределенное поведение, все может произойти. В вашем случае это проявляется как nan, являющийся результатом операции с участием V.