Thread: Odd division problems!

  1. #1
    Registered User
    Join Date
    Nov 2011
    Posts
    16

    Odd division problems!

    I won't post all my code (sorry!), its very long. Here's the relevant stuff...

    Code:
    int main(int argc, char* argv[]){
      int          dim, valid_input, particles;
      int          i=0, xpos, ypos, rnd;
      int          xsum, ysum, dim_count;
      int          j, k;
      double       xCoM, yCoM;
      FILE        *pos_output, *dim_output;
    . . . .
    Code:
          /* Calculates Centre of mass (CoM) */      xsum = 0;
          ysum = 0;
          for(i=0; i<dim+1; i++)
    	{
    	  for(j=0; j<dim+1; j++)
    	    {
    	      if(sites[i][j] == 1)
    		{
    		  xsum = xsum + i;
    		  ysum = ysum + j;
    		}
    	    }
    	}
          double a = (double) xsum;
          double b = (double) ysum;
          double d = (double) dim;
          printf("xsum = %ld \nysum = %ld \n", xsum, ysum);
          xCoM = a / d;
          yCoM = b / d;
    
    
          printf("CoM = ( %lf.3 , %lf.3 )\n", xCoM, yCoM);
    I know its a bit off to typecast like this, but for some reason EVERY time I do run the program I get sensible answers for xsum and ysum, but ridiculous answers for xCoM and yCoM - heres an example:

    xsum = 8
    ysum = 10
    CoM = ( 1073741824.3 , 0.3 )

    For some reason I always get yCoM = 0.3 and xCoM = something ridiculously large beginning with 107...

    WHAT?

  2. #2
    Registered User
    Join Date
    Nov 2011
    Posts
    16

    Actually before someone asks, heres the whole code:

    its very long!

    Code:
    /**
    ** gcc 1007189_prog2.c -lm
    ********************************************/
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    
    #define EXPECTED_ARGS   3
    
    
    /*****************************************
    ** stop function calculates whether
    ** particle should aggregate
    ** i.e. is any of its neighbours
    ** contain a particle
    **
    ** returns 0 to continue, 1 to stop
    **
    ** starts by assuming 0 (continue)
    ** then checks through all circumstances
    ** when particle is on the boundary and
    ** checks whether any of the neighbours
    ** contain a particle.
    ** 
    ** If xpos or ypos are outside the lattice
    ** for any reason it will continue
    **
    ** NOTE REQUIRES dim > 0 !!
    ******************************************/
    int stop(int dim, int xpos, int ypos, int sites[dim+1][dim+1])
     {
      int stop = 0;
    
    
      if(xpos == 0 && ypos == 0)
        {
          if(sites[0][1]!=0 || sites[1][0]!=0)
    	{
    	  stop = 1;
    	}
        }
      if(xpos == 0 && ypos == dim)
        {
          if(sites[0][dim-1]!=0 || sites[1][dim]!=0)
    	{
    	  stop = 1;
    	}
        }
      if(xpos == dim-1 && ypos == 0)
        {
          if(sites[dim-1][0]!=0 || sites [dim][1]!=0)
    	{
    	  stop =1;
    	}
        }
      if(xpos == dim && ypos == dim)
        {
          if(sites[dim-1][dim]!=0 || sites [dim][dim-1]!=0)
    	{
    	  stop =1;
    	}
        }
      if(xpos == 0 && ypos > 0 && ypos < dim)
        {
          if(sites[1][ypos]!=0 || sites[0][ypos+1]!=0 || sites[0][ypos-1]!=0)
    	{
    	  stop=1;
    	}
        }
      if(ypos == 0 && xpos > 0 && xpos < dim)
        {
          if(sites[xpos][1]!=0 || sites[xpos+1][0]!=0 || sites[xpos-1][0]!=0)
    	{
    	  stop=1;
    	}
        }
      if(xpos == dim  && ypos > 0 && ypos < dim)
        {
          if(sites[dim-1][ypos]!=0 || sites [dim][ypos+1]!=0 || sites[dim][ypos-1]!=0)
    	{
    	  stop=1;
    	}
        }
      if(ypos == dim  && xpos > 0 && xpos < dim)
        {
          if(sites[xpos][dim-1]!=0 || sites [xpos+1][dim]!=0 || sites[xpos-1][dim]!=0)
    	{
    	  stop=1;
    	}
        }
      if(xpos>0 && xpos<dim && ypos>0 && ypos<dim)
        {
          if(sites[xpos][ypos-1]!=0 || sites[xpos][ypos+1]!=0 || sites[xpos-1][ypos]!=0 || sites[xpos+1][ypos]!=0)
    	{
    	  stop=1;
    	}
        }
    
    
      return stop;
     }
    
    
    int main(int argc, char* argv[])
    {
      int          dim, valid_input, particles;
      int          i=0, xpos, ypos, rnd;
      int          xsum, ysum, dim_count;
      int          j, k;
      double       xCoM, yCoM;
      FILE        *pos_output, *dim_output;
    
    
    
    
      /* Get command line input */
      if(argc == EXPECTED_ARGS)
        {
          valid_input = sscanf(argv[1], "%ld", &dim);
          valid_input = valid_input && sscanf(argv[2],"%ld", &particles);
        }
      else
        {
          printf("***Enter program name followed by width of lattice followed by no. of particles***\n");
          valid_input = 0;
        }
    
    
      /* Checks dim > 1 */
      if(dim < 2)
        {
          printf("*** Width of lattive must be greater than or equal to 2 ***\n");
          valid_input = 0;
        }
    
    
      /* Checks particles isn't too large or small */
      if(particles > (dim+1)*(dim+1)-1 || particles < 1)
        {
          printf("*** Particles must be less than (width+1)^2 and greater than 0 ***\n");
          valid_input = 0;
        }
    
    
      /* Final validation */
      if(!valid_input)
        {
          printf("*** Input Validation failed! ***\n");
          return(EXIT_FAILURE);
        }
    
    
      /* Declare sites[][] which will say whether each site is occupy
      ** and declares all values to be zero */
      int sites[dim+1][dim+1];
      for(j=0; j<dim+1; j++)
        {
          for(k=0;k<dim+1;k++)
    	{
    	  sites[j][k]=0;
    	}
        }
    
    
      /* Places seed particle at centre (or one of the 4 sites close to the centre) */
      j = (int) ((double) (dim) /(double) (2));
      sites[j][j] = 1;
    
    
      /* Seed rand numbers */
      srand((int) time(NULL));
    
    
    
    
      /* Does the whole diffusion process for desired number of particles */
      while(i<particles)
        {
          rnd = (rand() % 4);
    
    
          if(rnd == 0)
    	{
    	  ypos = 0;
    	  xpos = (int) ( (dim-1) * (double) rand() / (double) (RAND_MAX) );
    	}
    
    
          if(rnd == 1)
    	{
    	  xpos = 0;
    	  ypos = (int) ( (dim-1) * (double) rand() / (double) (RAND_MAX) ) +1;
    	}
    
    
          if(rnd == 2)
    	{
    	  ypos = dim;
    	  xpos = (int) ( (dim-1) * (double) rand() / (double) (RAND_MAX) );
    	}
    
    
          if(rnd == 3)
    	{
    	  xpos = dim;
    	  ypos = (int) ( (dim-1) * (double) rand() / (double) (RAND_MAX) )+1;
    	}
          
          /* If site chosen above is occupied, repeats until non-occupied site is chosen */
          while(sites[xpos][ypos])
    	{
    	  
    	  rnd = (rand() % 4);
    
    
    	  if(rnd == 0)
    	    {
    	      ypos = 0;
    	      xpos = (int) ( (dim)* (double) rand() / (double) (RAND_MAX) );
    	    }
    
    
    	  if(rnd == 1)
    	    {
    	      xpos = 0;
    	      ypos = (int) ( (dim)* (double) rand() / (double) (RAND_MAX) );
    	    }
    
    
    	  if(rnd == 2)
    	    {
    	      ypos = dim;
    	      xpos = (int) ( (dim)* (double) rand() / (double) (RAND_MAX) );
    	    }
    	  
    	  if(rnd == 3)
    	    {
    	      xpos = dim;
    	      ypos = (int) ( (dim) * (double) rand() / (double) (RAND_MAX) );
    	    }
    	}
    
    
          /* Moves particle at random until aggregation */
          while(!stop(dim, xpos, ypos, sites))
    	{
    	  rnd = (rand() % 12);
    
    
    	  if(xpos == 0 && ypos == 0)
    	    {
    	      xpos = rnd < 6 ? xpos+1 : xpos;
    	      ypos = rnd >= 6 ? ypos+1 : ypos;
    	    }
    
    
    	  if(xpos == 0 && ypos == dim)
    	    {
    	      xpos = rnd < 6 ? xpos+1 : xpos;
    	      ypos = rnd >=6 ? ypos-1 : ypos;
    	    }
    
    
    	  if(xpos == dim && ypos == 0)
    	    {
    	      xpos = rnd < 6 ? xpos-1 : xpos;
    	      ypos = rnd >=6 ? ypos+1 : ypos;
    	    }
    
    
    	  if(xpos == dim && ypos == dim)
    	    {
    	      xpos = rnd < 6 ? xpos-1 : xpos;
    	      ypos = rnd >=6 ? ypos-1 : ypos;
    	    }
    
    
    	  if(xpos == 0 && ypos > 0 && ypos < dim)
    	    {
    	      xpos = rnd < 4 ? xpos+1 : xpos;
    	      ypos = rnd >= 4 && rnd < 8 ? ypos-1 : ypos;
    	      ypos = rnd >=8 ? ypos+1 : ypos;
    	    }
    
    
    	  if(ypos == 0 && xpos > 0 && xpos < dim)
    	    {
    	      ypos = rnd < 4 ? ypos+1 : ypos;
    	      xpos = rnd >= 4 && rnd < 8 ? xpos-1 : xpos;
    	      xpos = rnd >=8 ? xpos+1 : xpos;
    	    }
    
    
    	  if(xpos == dim && ypos > 0 && ypos < dim)
    	    {
    	      xpos = rnd < 4 ? xpos-1 : xpos;
    	      ypos = rnd >=4 && rnd < 8 ? ypos-1 : ypos;
    	      ypos = rnd >=8 ? ypos+1 : ypos;
    	    }
    	      
    	  if(ypos == dim && xpos > 0 && xpos < dim)
    	    {
    	      ypos = rnd < 4 ? ypos-1 : ypos;
    	      xpos = rnd >= 4 && rnd < 8 ? xpos-1 : xpos;
    	      xpos = rnd >=8 ? xpos+1 : xpos;
    	    }
    
    
    	  if(xpos > 0 && xpos < dim && ypos > 0 && ypos < dim)
    	    {
    	      xpos = rnd < 3 ? xpos-1 : xpos;
    	      xpos = rnd >=3 && rnd < 6 ? xpos+1 : xpos;
    	      ypos = rnd >=6 && rnd < 9 ? ypos-1 : ypos;
    	      ypos = rnd >=9 ? ypos+1 : ypos;
    	    }
    
    
    	}
    
    
    	/* Tells sites[][] that this position is now occupied */ 
    	sites[xpos][ypos] = 1;
    
    
    	i++;
    	}
    
    
          /* Calculates Centre of mass (CoM) */
          xsum = 0;
          ysum = 0;
          for(i=0; i<dim+1; i++)
    	{
    	  for(j=0; j<dim+1; j++)
    	    {
    	      if(sites[i][j] == 1)
    		{
    		  xsum = xsum + i;
    		  ysum = ysum + j;
    		}
    	    }
    	}
          double a = (double) xsum;
          double b = (double) ysum;
          double d = (double) dim;
          printf("xsum = %ld \nysum = %ld \n", xsum, ysum);
          xCoM = a / d;
          yCoM = b / d;
    
    
          printf("CoM = ( %lf.3 , %lf.3 )\n", xCoM, yCoM);
    
    
    
    
          pos_output = fopen("1007189_proj2_1.out","w");
          if(pos_output != (FILE*) NULL)
    	{
    	  for(i=0; i<dim+1; i++)
    	    {
    	      for(j=0; j<dim+1; j++)
    		{
    		  fprintf(pos_output, "%ld %ld %ld\n", i, j, sites[i][j]);
    		}
    	    }
    	  fclose(pos_output);
    	}
    
    
          
          /* Declares frac_dim[], which stores the number of particles
          ** within a given distance of the CoM */
          int frac_dim[1 + dim/2];
          
          for(i=0; i< 1 + dim/2; i++)
    	{
    	  dim_count = 0;
    	  for(j=0; j<dim+1; j++)
    	    {
    	      for(k=0; k<dim+1; k++)
    		{
    		  if( (j-xCoM)*(j-xCoM) + (k-yCoM)*(k-yCoM) < i*i && sites[i][j] == 1)
    		    {
    		      dim_count = dim_count + 1;
    		    }
    		}
    	    }
    	  frac_dim[i] = dim_count;
    	}
    
    
          dim_output = fopen("1007189_proj2_2.out","w");
          if(dim_output != (FILE*) NULL)
    	{
    	  for(i=0; i< 1 + dim/2; i++)
    	    {
    	      {
    		fprintf(dim_output, "%ld %ld\n", i, frac_dim[i]);
    	      }
    	    }
    	  fclose(dim_output);
    	}
    }

  3. #3
    Registered User
    Join Date
    Nov 2011
    Posts
    16
    oddly, its working now that I've included time.h, which I hadn't before.

    If anyone can explain this I'd be interested to know

  4. #4
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    Quote Originally Posted by tomh16 View Post
    oddly, its working now that I've included time.h, which I hadn't before. If anyone can explain this I'd be interested to know
    Undefined behavior can come and go with any change.

    You shouldn't be using %ld in your format specifiers since you are just using ints. Use %d instead.

    You should fix your spacing. Don't mix spaces and tabs.

    Also, you should divide it into functions. In general, a function should be no more than a page.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  5. #5
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Undefined behaviour is like that. Using a function in C without a declaration causes the compiler to assume all arguments are int and it returns int. If the function accepts different types of arguments, or returns a different type - both of which time() does - the results are undefined.

    Including the relevant header is a way to avoid such things.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  6. #6
    Registered User
    Join Date
    Nov 2011
    Posts
    16
    Does rand() work like that too? is there something I should include to use rand() ?

    Quote Originally Posted by grumpy View Post
    Undefined behaviour is like that. Using a function in C without a declaration causes the compiler to assume all arguments are int and it returns int. If the function accepts different types of arguments, or returns a different type - both of which time() does - the results are undefined.

    Including the relevant header is a way to avoid such things.

  7. #7
    Registered User
    Join Date
    Nov 2011
    Posts
    16
    Quote Originally Posted by oogabooga View Post
    Undefined behavior can come and go with any change.

    You shouldn't be using %ld in your format specifiers since you are just using ints. Use %d instead.

    You should fix your spacing. Don't mix spaces and tabs.

    Also, you should divide it into functions. In general, a function should be no more than a page.
    Thanks for the tips!

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by tomh16
    Does rand() work like that too? is there something I should include to use rand() ?
    Yes, #include <stdlib.h>
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Alright, a quick lesson on reducing duplication and using more appropriate language constructs:
    Code:
    	rnd = rand() % 4;
    	int tempPos = (int)(dim * (double)rand() / (double)RAND_MAX);
    	switch (rnd)
    	{
    		case 0:
    			ypos = 0;
    			xpos = tempPos;
    			break;
    		case 1:   
    			xpos = 0;
    			ypos = tempPos;
    			break;
    		case 2:       
    			ypos = dim;
    			xpos = tempPos;
    			break;
    		case 3:       
    			xpos = dim;
    			ypos = tempPos;
    			break;
    	}
    It can be done much more "cleverly" than this, but this should at least be pretty clear.
    It replaces lines 215 to 243 of your code.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 06-07-2011, 10:05 PM
  2. shifting? division?
    By kiros88 in forum C Programming
    Replies: 3
    Last Post: 06-09-2010, 02:10 PM
  3. division issue
    By surrounded in forum C Programming
    Replies: 3
    Last Post: 02-27-2009, 01:05 PM
  4. Division Result
    By anirban in forum Tech Board
    Replies: 19
    Last Post: 08-13-2008, 10:21 PM
  5. Division by 0
    By ajaxthegreater in forum A Brief History of Cprogramming.com
    Replies: 46
    Last Post: 10-08-2005, 04:21 PM