Computing Large Values

• 04-06-2005
swbluto
Computing Large Values
I have been making a planetary program to predict the paths of the planets.. but I'm working with very large values because I'm using meters as measurement(for compatability with the formula's) and also kilograms. So that means I'm using values to the 5e30, and then plugging them into the equations, I'm working with numbers as large as 5e60.

However my Dev-Cpp compiler doesn't seem like it can handle values this large. I do not care for precision... I just want to be able to compute these values. Thank you!

Error Messages:
150 integer constant is too large for "long" type

that's about all the error messages I get .. that is the only error I'm getting. here's the code, I know it's hard to follow, and can be simplified, but it's there. It usually pulls up this error right where masses of the planets are being calculated, where it's drawing the images in drawscene(), and where the values for mass, x_position, and y_velocity are being initialized.

BTW, this is for a HS senior project.

Code:

``` #include <stdio.h> #include <stdlib.h> #include <SDL.h> #include <math.h> #include <iostream.h> #define objects 10 #define G (6.667*(10^-11)) #define ScreenWidth 1024 #define ScreenHeighth 768 #define meterperpixel 18807782000//18807782 #define zoom 1 //the higher the number, the farther out the zoom, norm is 1 struct Body {       char name[15];       long double x_position,x_force,x_acceleration, x_velocity, y_position, y_force, y_acceleration, y_velocity, mass;       long double x_force_parts[objects];       long double y_force_parts[objects]; }; Body planet[objects]; SDL_Surface *back; SDL_Surface *image; SDL_Surface *screen; SDL_Surface *sun; SDL_Surface *mercury; SDL_Surface *venus; SDL_Surface *earth; SDL_Surface *mars; SDL_Surface *jupiter; SDL_Surface *saturn; SDL_Surface *uranus; SDL_Surface *neptune; SDL_Surface *pluto; int xpos=0,ypos=0; int InitImages() {   back = SDL_LoadBMP("background.bmp");   image = SDL_LoadBMP("ship.bmp");   sun = SDL_LoadBMP("images/sun.bmp");   mercury = SDL_LoadBMP("images/mercury.bmp");   venus = SDL_LoadBMP("images/venus.bmp");   earth = SDL_LoadBMP("images/earth.bmp");   mars = SDL_LoadBMP("images/mars.bmp");   jupiter = SDL_LoadBMP("images/jupiter.bmp");   saturn = SDL_LoadBMP("images/saturn.bmp");   uranus = SDL_LoadBMP("images/uranus.bmp");   neptune = SDL_LoadBMP("images/neptune.bmp");   pluto = SDL_LoadBMP("images/pluto.bmp");   return 0; } int InitVideoMode() {     if ( SDL_Init(SDL_INIT_AUDIO|SDL_INIT_VIDEO) < 0 )   {     printf("Unable to init SDL: %s\n", SDL_GetError());     exit(1);   }   atexit(SDL_Quit);   screen=SDL_SetVideoMode(ScreenWidth, ScreenHeighth,32,SDL_HWSURFACE|SDL_DOUBLEBUF);   if ( screen == NULL )   {     printf("Unable to set 640x480 video: %s\n", SDL_GetError());     exit(1);   } } void DrawIMG(SDL_Surface *img, int x, int y) {   SDL_Rect dest;   dest.x = x;   dest.y = y;   SDL_BlitSurface(img, NULL, screen, &dest); } void DrawIMG(SDL_Surface *img, int x, int y, int w, int h, int x2, int y2) {   SDL_Rect dest;   dest.x = x;   dest.y = y;   SDL_Rect dest2;   dest2.x = x2;   dest2.y = y2;   dest2.w = w;   dest2.h = h;   SDL_BlitSurface(img, &dest2, screen, &dest); } void DrawBG() {   DrawIMG(back, 0, 0); } void DrawScene() {   DrawIMG(back, 0, 0);   DrawIMG(sun, (int)((planet[0].x_position/(meterperpixel*zoom))+319), (int)((planet[0].y_position/(meterperpixel*zoom))+239));   DrawIMG(mercury, (int)((planet[1].x_position/(meterperpixel*zoom))+319), (int)((planet[1].y_position/(meterperpixel*zoom))+239));   DrawIMG(venus, (int)((planet[2].x_position/(meterperpixel*zoom))+319), (int)((planet[2].y_position/(meterperpixel*zoom))+239));   DrawIMG(earth, (int)((planet[3].x_position/(meterperpixel*zoom))+319), (int)((planet[3].y_position/(meterperpixel*zoom))+239));   DrawIMG(mars, (int)((planet[4].x_position/(meterperpixel*zoom))+319), (int)((planet[4].y_position/(meterperpixel*zoom))+239));   DrawIMG(jupiter,(int)((planet[5].x_position/(meterperpixel*zoom))+319), (int)((planet[5].y_position/(meterperpixel*zoom))+239));   DrawIMG(saturn, (int)((planet[6].x_position/(meterperpixel*zoom))+319), (int)((planet[6].y_position/(meterperpixel*zoom))+239));   DrawIMG(uranus, (int)((planet[7].x_position/(meterperpixel*zoom))+319), (int)((planet[7].y_position/(meterperpixel*zoom))+239));   DrawIMG(neptune, (int)((planet[8].x_position/(meterperpixel*zoom))+319), (int)((planet[8].y_position/(meterperpixel*zoom))+239));   DrawIMG(pluto, (int)((planet[9].x_position/(meterperpixel*zoom))+319), (int)((planet[9].y_position/(meterperpixel*zoom))+239));   SDL_Flip(screen); } int main(int argc, char *argv[]) {   Uint8* keys;   //double planets[objects][(2*(objects-1)+10)+1];//actually 0-8,0-26, double for precision         int totaltime=0;         int deltatime=1*60*60*24*50;/*this is the time interval between each calculation in position and force, in seconds*/         int input=0;         int j=0;         int current=0;         int other=0;         int objnum=0;         double dx=0;         double dy=0;         double massmultiple=0;         double dxdyroot=0;         for(j=0;j<objects;j++)     {           {             planet[j].x_velocity=0;             planet[j].x_force=0;             planet[j].x_acceleration=0;             planet[j].y_acceleration=0;             planet[j].y_force=0;             planet[j].y_position=0;           }     }     planet[0].mass=2*1000000000000000000000000000000;     planet[1].mass=3.302*100000000000000000000000;     planet[2].mass=4.8685*1000000000000000000000000;     planet[3].mass=5.9736*1000000000000000000000000;     planet[4].mass=0.64185*1000000000000000000000000;     planet[5].mass=1898.6*1000000000000000000000000;     planet[6].mass=568.46*1000000000000000000000000;     planet[7].mass=86.832*1000000000000000000000000;     planet[8].mass=102.43*1000000000000000000000000;     planet[9].mass=0.0125*1000000000000000000000000;         planet[0].x_position=0;//sun         planet[1].x_position=(57.91*10000000000);//distance from the sun in km, semimajor axis which means slowest         planet[2].x_position=(108.21*10000000000);//venus         planet[3].x_position=(149.60*10000000000);//earth         planet[4].x_position=(227.92*10000000000);//mars         planet[5].x_position=(778.57*10000000000);//jupiter         planet[6].x_position=(1,433.53*10000000000);//saturn         planet[7].x_position=(2,872.46*10000000000);//uranus         planet[8].x_position=(4,495.06*10000000000);//neptune         planet[9].x_position=(5906.38*10000000000);//pluto         planet[0].y_velocity=0;//y-vel(m/s)         planet[1].y_velocity=38.86*1000;//mercury         planet[2].y_velocity=34.79*1000;//venus         planet[3].y_velocity=29.29*1000;//earth         planet[4].y_velocity=21.97*1000;//mars         planet[5].y_velocity=12.44*1000;//jupiter         planet[6].y_velocity=9.09*1000;//saturn         planet[7].y_velocity=6.49*1000;//uranus         planet[8].y_velocity=5.37*1000;//neptune         planet[9].y_velocity=3.71*1000;//pluto         //Define the planet's values modeling the solar system   InitVideoMode();   InitImages();   DrawBG();   int done=0;   for(int z=0;z<1000;z++)//start of the program loop {                 for(current=0;current<objects;current++)//scroll through each planet calculating for force         {                   for(other=0;other<objects;other++)//to scroll through each interacting planet                   {  //temporary, x2 is the current planet, x1 is the current object, m is mass respectively                                                                 if(current!=other)//don't want to solve for the planet's own gravitational effect on itself :)                                 {                                                 dx=planet[current].x_position-planet[other].x_position;                                                 dy=planet[current].y_position-planet[other].y_position;                                                 massmultiple=planet[other].mass*planet[current].mass;                                                 dxdyroot = (sqrt((dy)*(dy)+(dx)*(dx)));                                                 if(dx!=0 || dy!=0)                                                 {                                                         planet[current].x_force_parts[other]=(G*(-1*dx)*(massmultiple))/(dxdyroot*dxdyroot*dxdyroot);//edit const. modifiers-EDITED for relative position for force inside the table, i.e.[objnumber+"6"])                                                         planet[current].y_force_parts[other]=(G*(-1*dy)*(massmultiple))/(dxdyroot*dxdyroot*dxdyroot);//edit const. modifiers-EDITED for relative position for force inside the table, i.e.[objnumber+"6"])                                                 }                                 }                   }         }//finish solving for each planet's individual force vectors on each other, identified as the X-force vector and the Y-force vectors... now to sum the forces.         for(current=0;current<objects;current++)//scroll through each planet         {planet[current].x_force=0;//Resetting the Force Sum for each planet           planet[current].y_force=0;                   for(other=0;other<objects;other++)//to scroll through each interacting planet                   {                                 planet[current].x_force+=planet[current].x_force_parts[other]; //17 the special cell for the total sum force, solving for total x-force                                 planet[current].y_force+=planet[current].y_force_parts[other]; //same as before                   }         }         /*now that we solved for each sum force vector on each planet, solve for the acceleration, and then final velocity, and then change in position, now for one axis at a time*/         /*solve for acceleration, based on force F=MA, we know m and f so solve for A which is equal to F/M */         for(current=0;current<objects;current++)         {                   planet[current].x_acceleration=planet[current].x_force/planet[current].mass;//3 is acceleration, for x, km/s^2                   planet[current].x_velocity+=planet[current].x_acceleration*deltatime;//4 is velocity, the new velocity is equal V+A(T), now that we have the x-velocity                   planet[current].x_position+=planet[current].x_velocity*deltatime; //1 is the x-coordinate;                   planet[current].y_acceleration=planet[current].y_force/planet[current].mass;//6 is acceleration, for y, in m/s(??)                   planet[current].y_velocity+=planet[current].y_acceleration*deltatime;//7 is the y-velocity, I typed in planets[j][0] instead of deltatime, why? Is something going wrong with my logic?                   planet[current].y_position+=planet[current].y_velocity*deltatime;// 2 is the y-coordinate;         }         totaltime+=deltatime;                                                                                         /*for(j=0;j<(2*(objects-1)+10);j++)                                                                                                                                 {                                                                                                                                                                 cout<<planets[0][j]<<endl;                                                                                                                                                                     getch();                                                                                                                                                               //printf("/n");                                                                                                                       }//Diagnostic purposes only */                                                                                                                       //cin>>input; add a get key function         //here is the part where we take the planets x and y coordinate and translate them into screen coordinates for display, we can put pictures in place of this.. etc. Whatever you want. DrawScene(); }//end of the program loop /*GETKEY FUNCTION to halt the program before exit*/     return 1; }```
• 04-06-2005
stumpster123
I don't know of any data type that can hold a value as large as 5e60 that is a gigantic number and a double will never be able to hold that it goes to like 2e9 about. Maybe you could just take away multiplying by like a billion and just work with the small numbers.

Print that number and try adding the correct amount of zeroes to the end. Not completely sure how you could do it. Possibly with some calculations and set the width for the 0's. Hope this gives you an idea.
• 04-06-2005
swbluto
yes.. I could place in substitute values for the larger ones, but the thing is that one of the variables must compensate for the change, and the the formula's work out for the same large number.. So I just need a to know a way that can compute extremely large values (Cuz my brain would hurt too much after programming that to think of any other way, with substitution,etc.)
• 04-06-2005
stumpster123
Well thats the problem there are no data types that can fit numbers that large especially double. I know there is a quad type, which is 128 bits, but its only for special machines and i dont even think it could hold a number that large.

Do you have to use meters i mean you could just convert everything to a larger measurement like km/kg or even larger units than that because it wont cut down the size that much.
• 04-06-2005
swbluto
I could convert it to some other larger measurement, but I would have to think about everything to see how it would fit in the whole of the program. Plus I would have to edit some constant values in the formula's to compensate for the change in units.. ick, but it looks like that's my only alternative. Thanks!
• 04-06-2005
Quote:

ick, but it looks like that's my only alternative. Thanks!
Nope, http://www.swox.com/gmp/ should do the trick

EDIT
Quote:

a double will never be able to hold that it goes to like 2e9 about
from http://msdn.microsoft.com/library/de...reftable_1.asp

double = 1.7E +/- 308 (15 digits)
• 04-06-2005
FlyingDutchMan
As far as I can tell it trying to convert your 100000000...00000s into long ints which would never work. Put .0 on the end each one and it might just work (so it inteprets it as a float instead of int).
• 04-06-2005
stumpster123
Quote:

double = 1.7E +/- 308 (15 digits)
Yeah I was just too lazy to look it up but it still wouldnt fit
• 04-07-2005
Sang-drax
Quote:

Originally Posted by stumpster123
Yeah I was just too lazy to look it up but it still wouldnt fit

What do you mean? 5 * 10^60 is alot smaller than 1.7 * 10^308

It will work prefectly with doubles.

`2*1000000000000000000000000000000`
`2.0e30`