weird output for equations...

B

Blah

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;
}
}
 
O

osmium

Blah said:
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?

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.
 
E

eriwik

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?
 
R

Ron Natalie

Blah said:
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...
 
B

BobR

Ron Natalie wrote in message ...
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

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?
 
B

Blah

Ron said:
semicolons and newlines cost you nothing and make your code more
readable.
The if here is entirely redundant with the while.

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();
}

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?
 
B

Blah

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?

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.
 
B

BobR

Blah wrote in message ...
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. ]
 
B

Blah

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. ]


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"
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,576
Members
45,054
Latest member
LucyCarper

Latest Threads

Top