weird output for equations...

Discussion in 'C++' started by Blah, Dec 11, 2006.

  1. Blah

    Blah Guest

    Hi, this is a small program to print out three lists of values. One is
    a simple increment count the others are values from two equations. I've
    run this without problems before but when I've put in the new equations
    I sometimes get columns of -1.#IND. I think it might have something to
    do with using a wrong type or not including some important library
    file, but I'm not sure and google has been little help. Anyone know the
    problem?

    Thanks...



    #include <iostream> // for std::cout
    #include <fstream>
    #include <iomanip>
    using namespace std;
    void choice();

    double xnext, ynext, i;

    double step = 0.0001;
    double x = 10;
    double r = 1.00;
    double k = 5000.;
    double d = .001;
    double y = 5.;
    double p = .5;
    double a = .001;
    double count = 0;
    double count2 = 0;
    double count3 = 0;



    int main()
    {
    int vart;

    cout << "1. x=" << x << endl << "2. r=" << r << endl << "3. k=" << k
    << endl << "4. d=" << d << endl;
    cout << "5. y=" << y << endl << "6. p=" << p << endl << "7. a=" << a
    << endl<< "8. step=" << step << endl;
    cout << "Do you want to change something? 1= yes 2 = no" << endl;
    cin >> vart;


    if (vart == 1)
    {
    while (vart == 1)
    {
    choice();
    cout << "1. x=" << x << endl << "2. r=" << r << endl << "3. k=" << k
    << endl << "4. d=" << d << endl;
    cout << "5. y=" << y << endl << "6. p=" << p << endl << "7. a=" << a
    << endl<< "8. step=" << step << endl;
    cout << "Do you want to change something?" << endl;
    cin >> vart;

    }
    }


    ofstream dataout;

    dataout.open("res.dat", ios::eek:ut);

    for (i = 1; i <= 500000; i++)
    {
    count = count + 1;
    count2 = count2 + 1;
    count3 = count3 + 1;


    if (count2 == 1000)
    {
    cout << step*i << std::endl;
    count2 = 0;

    }

    xnext = (r*x*(1-x/k))-(d*x)-(p*x*y);



    ynext = (p*x*y)-(a*y);
    x = xnext;
    y = ynext;


    if (count == 100)
    {
    dataout.precision(10);
    dataout << i*step << " " << x << " " << y <<
    std::endl;
    count = 0;

    }


    }





    dataout.close();
    return 0;
    }



    void choice()
    {
    int choice;


    cout<< "what do you wish to change?" << endl;
    cin >> choice;

    switch (choice)

    {
    case 1:
    cin >> x;
    break;
    case 2:
    cin >> r;
    break;
    case 3:
    cin >> k;
    break;
    case 4:
    cin >> d;
    break;
    case 5:
    cin >> y;
    break;
    case 6:
    cin >> p;
    break;
    case 7:
    cin >> a;
    break;
    case 8:
    cin >> step;
    break;

    default:
    cout << "value of x unknown" << endl;
    }
    }
     
    Blah, Dec 11, 2006
    #1
    1. Advertising

  2. Blah

    osmium Guest

    "Blah" wrote:

    > Hi, this is a small program to print out three lists of values. One is
    > a simple increment count the others are values from two equations. I've
    > run this without problems before but when I've put in the new equations
    > I sometimes get columns of -1.#IND. I think it might have something to
    > do with using a wrong type or not including some important library
    > file, but I'm not sure and google has been little help. Anyone know the
    > problem?


    <snip>

    > void choice()
    > {
    > int choice;


    I have no idea what this program is supposed to do or what your problem is
    but I have a strong distaste for using one word for two different things in
    the same program.
     
    osmium, Dec 11, 2006
    #2
    1. Advertising

  3. Blah

    Guest

    On Dec 11, 3:30 am, "Blah" <> wrote:
    > Hi, this is a small program to print out three lists of values. One is
    > a simple increment count the others are values from two equations. I've
    > run this without problems before but when I've put in the new equations
    > I sometimes get columns of -1.#IND. I think it might have something to
    > do with using a wrong type or not including some important library
    > file, but I'm not sure and google has been little help. Anyone know the
    > problem?


    Haven't lookt at your code but are you sure you have initialized all
    variables correctly?

    --
    Erik Wikström
     
    , Dec 11, 2006
    #3
  4. Blah

    Ron Natalie Guest

    Blah wrote:

    >
    > int main()
    > {
    > int vart;
    >
    > cout << "1. x=" << x << endl << "2. r=" << r << endl << "3. k=" << k
    > << endl << "4. d=" << d << endl;


    semicolons and newlines cost you nothing and make your code more
    readable.
    >
    > if (vart == 1)
    > {
    > while (vart == 1)

    The if here is entirely redundant with the while.

    > {
    > choice();
    > cout << "1. x=" << x << endl << "2. r=" << r << endl << "3. k=" << k
    > << endl << "4. d=" << d << endl;
    > cout << "5. y=" << y << endl << "6. p=" << p << endl << "7. a=" << a
    > << endl<< "8. step=" << step << endl;
    > cout << "Do you want to change something?" << endl;
    > cin >> vart;
    >
    > }
    > }

    This apepars to be largely a repeat of thestuff at the beginning of
    main. You know you can do soething like:
    while(true) {
    // all those couts...
    cin >> vart;
    if(vart !- 1) break;
    choice();
    }

    >
    > xnext = (r*x*(1-x/k))-(d*x)-(p*x*y);
    >
    >

    Most likely you're abusing the floating point math. What is
    the value of k for the failing case? etc...
     
    Ron Natalie, Dec 11, 2006
    #4
  5. Blah

    BobR Guest

    Ron Natalie wrote in message ...
    >Blah wrote:
    >
    >> int main(){
    >> cin >> vart;
    >>

    >This apepars to be largely a repeat of thestuff at the beginning of
    >main. You know you can do soething like:
    > while(true) {
    > // all those couts...
    > cin >> vart;

    //> if(vart !- 1) break;
    if( vart != 1 ) break;

    > choice();
    > }


    Add for OP:

    ofstream dataout("res.dat");
    dataout.setf( std::ios_base::fixed ); // for test
    dataout.precision( 400 ); // for test

    >
    >>
    >> xnext = (r*x*(1-x/k))-(d*x)-(p*x*y);


    dataout<< xnext <<std::endl;

    >>
    >>

    >Most likely you're abusing the floating point math. What is
    >the value of k for the failing case? etc...


    I'll bet you (the OP) are running on an windows machine. Very big and very
    small double numbers hit a wall at the OS level (streams). Try it on a
    GNU/Linux machine.

    Try this:
    // #include <limits> <iostream> <iomanip>
    { // main or function.
    using std::cout // for NG post
    std::string DblMax("");
    {
    std::eek:stringstream out;
    out.setf(std::ios_base::fixed);
    out.precision(400);
    double tmp( std::numeric_limits<double>::max() / 1.0e+276);
    out<<(tmp);
    DblMax=out.str();
    }
    cout <<"DblMax=out.str() = "<<DblMax<<endl;
    DblMax = "";
    {
    std::eek:stringstream out;
    out.setf(std::ios_base::fixed);
    out.precision(400);
    double tmp( std::numeric_limits<double>::max() / 1.0e+275); // note
    change
    out<<(tmp);
    DblMax=out.str();
    }
    cout <<"DblMax=out.str() = "<<DblMax<<endl;
    } // end


    Your findings?

    --
    Bob R
    POVrookie
     
    BobR, Dec 11, 2006
    #5
  6. Blah

    Blah Guest

    Ron Natalie wrote:
    > Blah wrote:
    >
    > >
    > > int main()
    > > {
    > > int vart;
    > >
    > > cout << "1. x=" << x << endl << "2. r=" << r << endl << "3. k=" << k
    > > << endl << "4. d=" << d << endl;

    >
    > semicolons and newlines cost you nothing and make your code more
    > readable.
    > >
    > > if (vart == 1)
    > > {
    > > while (vart == 1)

    > The if here is entirely redundant with the while.
    >
    > > {
    > > choice();
    > > cout << "1. x=" << x << endl << "2. r=" << r << endl << "3. k=" << k
    > > << endl << "4. d=" << d << endl;
    > > cout << "5. y=" << y << endl << "6. p=" << p << endl << "7. a=" << a
    > > << endl<< "8. step=" << step << endl;
    > > cout << "Do you want to change something?" << endl;
    > > cin >> vart;
    > >
    > > }
    > > }

    > This apepars to be largely a repeat of thestuff at the beginning of
    > main. You know you can do soething like:
    > while(true) {
    > // all those couts...
    > cin >> vart;
    > if(vart !- 1) break;
    > choice();
    > }
    >
    > >
    > > xnext = (r*x*(1-x/k))-(d*x)-(p*x*y);
    > >
    > >

    > Most likely you're abusing the floating point math. What is
    > the value of k for the failing case? etc...


    k fails at 5000 which is the case here...although reducing it to 10
    doesn't help. I've only been able to get it to work a few times by
    playing with the variables. For example, changing x and y to .5 will
    prevent the #INDs. I don't know the magic limit where it will change
    though. The lower the starting values of the variables which increase
    the output values (especially r) the more likely it will not give
    -1.#IND lists (but the values for both equations quickly go to zero
    which is not what I want). It would seem getting output values that are
    too high or too low might be the problem but wouldn't setting precision
    take care of this? Is there some library files I can include to fix
    this? Or maybe a more appropriate type?
     
    Blah, Dec 14, 2006
    #6
  7. Blah

    Blah Guest


    > I'll bet you (the OP) are running on an windows machine. Very big and very
    > small double numbers hit a wall at the OS level (streams). Try it on a
    > GNU/Linux machine.
    >
    > Try this:
    > // #include <limits> <iostream> <iomanip>
    > { // main or function.
    > using std::cout // for NG post
    > std::string DblMax("");
    > {
    > std::eek:stringstream out;
    > out.setf(std::ios_base::fixed);
    > out.precision(400);
    > double tmp( std::numeric_limits<double>::max() / 1.0e+276);
    > out<<(tmp);
    > DblMax=out.str();
    > }
    > cout <<"DblMax=out.str() = "<<DblMax<<endl;
    > DblMax = "";
    > {
    > std::eek:stringstream out;
    > out.setf(std::ios_base::fixed);
    > out.precision(400);
    > double tmp( std::numeric_limits<double>::max() / 1.0e+275); // note
    > change
    > out<<(tmp);
    > DblMax=out.str();
    > }
    > cout <<"DblMax=out.str() = "<<DblMax<<endl;
    > } // end
    >
    >
    > Your findings?
    >
    > --
    > Bob R
    > POVrookie


    I'm sorry, I'm inexperienced so I could not get the code to work. Did
    you intend it to be run as a stand alone test? I don't have a Linux box
    at the moment but I guess I can get access to one soon.
     
    Blah, Dec 14, 2006
    #7
  8. Blah

    BobR Guest

    Blah wrote in message ...
    >
    >Ron Natalie wrote:
    >>
    >> Most likely you're abusing the floating point math. What is
    >> the value of k for the failing case? etc...

    >
    >k fails at 5000 which is the case here...although reducing it to 10
    >doesn't help. I've only been able to get it to work a few times by
    >playing with the variables. For example, changing x and y to .5 will
    >prevent the #INDs. I don't know the magic limit where it will change
    >though. The lower the starting values of the variables which increase
    >the output values (especially r) the more likely it will not give
    >-1.#IND lists (but the values for both equations quickly go to zero
    >which is not what I want). It would seem getting output values that are
    >too high or too low might be the problem but wouldn't setting precision
    >take care of this? Is there some library files I can include to fix
    >this? Or maybe a more appropriate type?


    The -1.#IND is a windows thing. On GNU it most likely will output the full
    number (several lines of it, many zeros).
    Only thing to do is test against the numeric limits[1] and output 'fixed' or
    'scientific' depending.

    There are some 3rd party large-number libraries around.

    [1] /*
    struct numeric_limits<double>{
    static double min();
    static double max();
    static double epsilon();
    static double round_error();
    static double infinity();
    static double quiet_NaN();
    static double signaling_NaN();
    static double denorm_min();
    };
    */


    This is butt-ugly, but, I put this together to see output on a windows
    machine:

    #include <iostream>
    #include <ostream> // std::endl
    #include <sstream> // I forgot this in other post
    #include <string> // ..and this <~G>
    #include <limits>
    #include <iomanip>

    int main(){
    { // positive number only
    using std::cout; // for NG posts.
    std::stringstream temp;
    temp.precision(400);
    temp << std::numeric_limits<double>::max();
    temp.setf(std::ios_base::fixed); // no effect here, could remove
    std::string to;
    temp >> to;
    size_t dpoint( to.find('.') );
    size_t de( to.find('e') ); // could be 'E'
    std::string whole( to.substr(0, dpoint) );
    std::string frac( to.substr( dpoint+1, (de - dpoint)-1));
    std::string expon( to.substr( de+2 ) ); // skip 'e+'
    int sz;
    { std::istringstream sis( expon.c_str() ); sis >> sz; }
    sz -= frac.size();
    std::string toadd( sz, '0' );
    std::string final = whole + frac + toadd + ".000";
    cout <<" final = "<<final<<std::endl;
    cout <<" final.size() = "<<final.size()<<std::endl;
    cout<<std::endl;
    }
    return 0;
    } // main()

    // temp >> string to = 1.7976931348623157e+308
    // note: line breaks inserted for NG post.
    // final = 1797693134862315700000000000000000000000000000000
    000000000000000000000000000000000000000000000000000000000
    000000000000000000000000000000000000000000000000000000000
    000000000000000000000000000000000000000000000000000000000
    000000000000000000000000000000000000000000000000000000000
    00000000000000000000000000000000.000
    // final.size() = 313

    I wouldn't trust the accuracy of that, it's just for exhibit.

    On a GNU/Linux machine, all you'd do is:

    {
    using std::cout; // for NG posts.
    cout.precision( 400 );
    cout.setf( std::ios_base::fixed );
    cout << std::numeric_limits<double>::max() <<std::endl;
    }

    Try that on your windows machine. Work?
    (if 'yes', what win version? what (date) 'msvcrt.dll'? (where the bug
    is[2])).

    [2] - I think the critical buffer may be size 255 (where 310+ is needed).
    [ experts, feel free to correct me. ]
    --
    Bob R
    POVrookie
     
    BobR, Dec 14, 2006
    #8
  9. Blah

    Blah Guest


    >
    > There are some 3rd party large-number libraries around.
    >
    > [1] /*
    > struct numeric_limits<double>{
    > static double min();
    > static double max();
    > static double epsilon();
    > static double round_error();
    > static double infinity();
    > static double quiet_NaN();
    > static double signaling_NaN();
    > static double denorm_min();
    > };
    > */
    >
    >
    > This is butt-ugly, but, I put this together to see output on a windows
    > machine:
    >
    > #include <iostream>
    > #include <ostream> // std::endl
    > #include <sstream> // I forgot this in other post
    > #include <string> // ..and this <~G>
    > #include <limits>
    > #include <iomanip>
    >
    > int main(){
    > { // positive number only
    > using std::cout; // for NG posts.
    > std::stringstream temp;
    > temp.precision(400);
    > temp << std::numeric_limits<double>::max();
    > temp.setf(std::ios_base::fixed); // no effect here, could remove
    > std::string to;
    > temp >> to;
    > size_t dpoint( to.find('.') );
    > size_t de( to.find('e') ); // could be 'E'
    > std::string whole( to.substr(0, dpoint) );
    > std::string frac( to.substr( dpoint+1, (de - dpoint)-1));
    > std::string expon( to.substr( de+2 ) ); // skip 'e+'
    > int sz;
    > { std::istringstream sis( expon.c_str() ); sis >> sz; }
    > sz -= frac.size();
    > std::string toadd( sz, '0' );
    > std::string final = whole + frac + toadd + ".000";
    > cout <<" final = "<<final<<std::endl;
    > cout <<" final.size() = "<<final.size()<<std::endl;
    > cout<<std::endl;
    > }
    > return 0;
    > } // main()
    >
    > // temp >> string to = 1.7976931348623157e+308
    > // note: line breaks inserted for NG post.
    > // final = 1797693134862315700000000000000000000000000000000
    > 000000000000000000000000000000000000000000000000000000000
    > 000000000000000000000000000000000000000000000000000000000
    > 000000000000000000000000000000000000000000000000000000000
    > 000000000000000000000000000000000000000000000000000000000
    > 00000000000000000000000000000000.000
    > // final.size() = 313
    >
    > I wouldn't trust the accuracy of that, it's just for exhibit.
    >



    > Try that on your windows machine. Work?
    > (if 'yes', what win version? what (date) 'msvcrt.dll'? (where the bug
    > is[2])).
    >
    > [2] - I think the critical buffer may be size 255 (where 310+ is needed).
    > [ experts, feel free to correct me. ]
    > --
    > Bob R
    > POVrookie



    I tried the above code but although it built correctly, running gave
    the "this application has asked runtime to terminate in in an unusual
    way"
     
    Blah, Dec 17, 2006
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. buke2
    Replies:
    2
    Views:
    538
    buke2
    Jul 28, 2004
  2. Hendrik Greving

    design boolean equations

    Hendrik Greving, Jun 16, 2005, in forum: VHDL
    Replies:
    2
    Views:
    523
  3. Replies:
    1
    Views:
    1,215
    Roedy Green
    Nov 15, 2005
  4. munehiro

    parsing equations

    munehiro, Dec 9, 2003, in forum: Python
    Replies:
    4
    Views:
    513
    munehiro
    Dec 9, 2003
  5. Paddy McCarthy

    combining several lambda equations

    Paddy McCarthy, Feb 18, 2005, in forum: Python
    Replies:
    7
    Views:
    319
    Steven Bethard
    Feb 21, 2005
Loading...

Share This Page