Issue with Filling Array

• 08-30-2011
sam.briggs
Issue with Filling Array
Hello Everyone,

I'm a first year, going on second year, chemical physicist and over the summer I've been tasked with writing a programme in C. I've not had any experience of programming before and we've only had five lectures and been given some very rudimentary notes. So I've been reading around and having a go at some basic bits and then had a stab at my assignment. Now I've come unstuck. I'm supposed to be creating a programme that allows me to generate a set of random numbers between 0 and 1 and then 'bin' them in an array and then be able to read how many random numbers are in each bin to calculate the distribution of the numbers, presumably to find out whether they're actually random or not! So here's what I've written so far:

Code:

```/*  *  Organization:  Dept. of Physics of Bristol University  *  Programmer:    Sam Briggs  *  Date:          27/08/11  *  *  Purpose:        Assesed Exercise; Distribution of Random Numbers  */ #include <stdio.h> #include <stdlib.h> #include <math.h> #define N 10                            //Define size of array to bin data int main()                              //Main Function Invocation {     int q, i, j;                          //Create Array Subscript integer variable     double x;     int databins[N][N];                    //Create Array to bin data     for (q=0; q<N; q++)         {             x=rand()/(double)RAND_MAX;                      //Generate Random Number between 0 and 1             printf("The random numbers are: %d:%f\n", q,x);             if ((x>=0)&&(x<(N/10)))         {             databins[0][i]=x;         }         else if((x>=(N/10))&&(x<((N/10)*2)))         {             databins[1][i]=x;         }         else if((x>=((N/10)*2))&&(x<((N/10)*3)))         {             databins[2][i]=x;         }         else if((x>=((N/10)*3))&&(x<((N/10)*4)))         {             databins[3][i]=x;         }         else if((x>=((N/10)*4))&&(x<((N/10)*5)))         {             databins[4][i]=x;         }         else if((x>=((N/10)*5))&&(x<((N/10)*6)))         {             databins[5][i]=x;         }         else if((x>=((N/10)*6))&&(x<((N/10)*7)))         {             databins[6][i]=x;         }         else if((x>=((N/10)*7))&&(x<((N/10)*8)))         {             databins[7][i]=x;         }         else if((x>=((N/10)*8))&&(x<((N/10)*9)))         {             databins[8][i]=x;         }         else if((x>=((N/10)*9))&&(x<N))         {             databins[9][i]=x;         }         else         {             databins[j][i]=0.0;         }         } printf("\nHere follow the Databins:\n\n");         for (i=0; i<N; i++)                                //Print All Array Entries             {                 for (j=0; j<N; j++)                 {                     printf("%f", databins[j]);                 }                 printf("\n");             }         return 0; }```
I'm at this point trying to get the random numbers into the array but I can't seem to get it to work. I don't want a set of code just some suggestions on how to get this to work, I apologise if my code offends anyone but hey, first time!!! Cheers guys.
• 08-30-2011
MK27
Quote:

Originally Posted by sam.briggs
I'm supposed to be creating a programme that allows me to generate a set of random numbers between 0 and 1 and then 'bin' them in an array and then be able to read how many random numbers are in each bin to calculate the distribution of the numbers, presumably to find out whether they're actually random or not!

Here's a little spoiler on the chance that you have not read or noticed the truth yet:
They are not random, because computers can't do that. However the algorithm that produces them may be sufficiently complex that it can't be easily reverse engineered, it which case they will seem random. So you can find out whether it is possible for you to tell the difference.

Note that unless you use srand() to seed the "random" number generator first, you will always get the same sequence of numbers.

WRT to your logic, there are some flaws.

Code:

```  double x;     int databins[N][N];                    //Create Array to bin data     for (q=0; q<N; q++)         {             x=rand()/(double)RAND_MAX;                      //Generate Random Number between 0 and 1             printf("The random numbers are: %d:%f\n", q,x);             if ((x>=0)&&(x<(N/10)))         {             databins[0][i]=x;```
Int values are integers. If you place a double value into one, it will be rounded down. Since x is between 0 and 1, you will always be assigning 0 to your int bin in this procedure (except for the rare instance where rand() generates RAND_MAX). I'd assume what you really want to do is zero all the bins out first, and then increment them by one each time they get hit, to give you a distribution count.

Then, of course, if N == 10, your first condition is almost guaranteed to match everything. x will be >=0, and there is only a 1 in RAND_MAX chance that it will not be < N/10 (1).

You can zero out the array by initializing it this way:

Code:

`  int databins[N][N] = { 0 };`
Otherwise, it will be "initialized" with data even more random than what you are about to put into it ;)
• 08-30-2011
rogster001
One problem you have here is that you have not initialised the ' i ' variable, this means [0][i] refers to an unknowable value, as a general rule remember to 'zero your ints'
• 08-30-2011
sam.briggs
Thank you so much! Its kind of just clicked in my head! XD
• 09-05-2011
sam.briggs
Ok so I've updated my code to this:
Code:

``` /*  *  Organization:  Dept. of Physics of Bristol University  *  Programmer:    Sam Briggs  *  Date:          27/08/11  *  *  Purpose:        Assesed Exercise; Distribution of Random Numbers  */ #include <stdio.h> #include <stdlib.h> #include <math.h> #define N 10                              //Define size of array to bin data int main()                                //Main Function Invocation {     int i;                                //Create Array Subscript integer variable     double x;     int databins[] = {0};                //Create Array to bin data     for(i=0; i<N; i++)     {         x=rand()/(double)RAND_MAX;        //Generate Random Number between 0 and 1         printf("The random numbers are: %d: %f\n", i,x);         if ((x>=0)&&(x<(N/100)))              //Increment bin value by one for each 'hit' from random number         {             databins[0]=databins[0]++;         }         else if((x>=(N/100))&&(x<((N/100)*2)))         {             databins[1]=databins[1]++;         }         else if((x>=((N/100)*2))&&(x<((N/100)*3)))         {             databins[2]=databins[2]++;         }         else if((x>=((N/100)*3))&&(x<((N/100)*4)))         {             databins[3]=databins[3]++;         }         else if((x>=((N/100)*4))&&(x<((N/100)*5)))         {             databins[4]=databins[4]++;         }         else if((x>=((N/100)*5))&&(x<((N/100)*6)))         {             databins[5]=databins[5]++;         }         else if((x>=((N/100)*6))&&(x<((N/100)*7)))         {             databins[6]=databins[6]++;         }         else if((x>=((N/100)*7))&&(x<((N/100)*8)))         {             databins[7]=databins[7]++;         }         else if((x>=((N/100)*8))&&(x<((N/100)*9)))         {             databins[8]=databins[8]++;         }         else if((x>=((N/100)*9))&&(x<N/100))         {             databins[9]=databins[9]++;         }     } printf("\nHere follow the Databins:\n\n");          //Print the databins to reveal how many hits     for(i=0; i<N; i++)     {         printf("Databin %d : %d\n", i, databins[i]);     }         return 0; }```
But the Array doesn't increment, it just gives random numbers in a few of the 'bins'. Any more advice? Cheers.
• 09-05-2011
itCbitC
That's because
Code:

`int databins[] = {0};`
creates a one not ten element array.
• 09-05-2011
MK27
You are still getting random garbage in your bins because this:

Code:

`    int databins[] = {0};                //Create Array to bin data`
[] indicates this is a single pointer, and that is all that gets zero'd. Also, by then accessing an array beyond index 0, you have gone out of bounds. When a) get the for loop fixed and b) starting adding more to the program, this will seg fault.

You want something like int databins[10] = {0}.

After that, you still have some issues with numerical types in C. Try this:

Code:

```printf("%lf\n", N/200*3); printf("%lf\n", (double)(N/200*3)); printf("%lf\n", (double)N/200*3); printf("%lf\n", N/200.0*3.0);```
The first two report 0.000 because this is an int value rounded down. Notice the first one is the form you've used, so all of your conditions are if (x >= 0.0 && x <= 0.0). Notice that using a decimal point (such as 3.0) implicitly casts that number to a double (and 3.0f casts to float).

Pay special attention to the printf in red; because the statement is paranthesized, the cast will not work. You have a lot of (unnecessary) parentheses which will complicate things. I'd recommend something like:

Code:

`      else if(x>=(double)N/100 && x<(double)N/100*2)`
When in doubt, printf("%lf") your statement to make sure it has the value you think it does.

After fixing that stuff, your logic is fine and the program will work.
• 09-05-2011
CommonTater
I'm no matemetician but it looks like all this:
Code:

```        x=rand()/(double)RAND_MAX;        //Generate Random Number between 0 and 1         printf("The random numbers are: %d: %f\n", i,x);         if ((x>=0)&&(x<(N/100)))              //Increment bin value by one for each 'hit' from random number         {             databins[0]=databins[0]++;         }         else if((x>=(N/100))&&(x<((N/100)*2)))         {             databins[1]=databins[1]++;         }         else if((x>=((N/100)*2))&&(x<((N/100)*3)))         {             databins[2]=databins[2]++;         }         else if((x>=((N/100)*3))&&(x<((N/100)*4)))         {             databins[3]=databins[3]++;         }         else if((x>=((N/100)*4))&&(x<((N/100)*5)))         {             databins[4]=databins[4]++;         }         else if((x>=((N/100)*5))&&(x<((N/100)*6)))         {             databins[5]=databins[5]++;         }         else if((x>=((N/100)*6))&&(x<((N/100)*7)))         {             databins[6]=databins[6]++;         }         else if((x>=((N/100)*7))&&(x<((N/100)*8)))         {             databins[7]=databins[7]++;         }         else if((x>=((N/100)*8))&&(x<((N/100)*9)))         {             databins[8]=databins[8]++;         }         else if((x>=((N/100)*9))&&(x<N/100))         {             databins[9]=databins[9]++;         }     }```
Can be reduced to...
Code:

```x = rand()/(double)RAND_MAX; printf("The random numbers are: %d: %f\n", i,x); databin[(int)(x * 10)]++;```
Even more interestingly, since the distribution would be the same for any given multiplier/divisor, you could simplify it even further, getting this...
Code:

```int x; x = rand()%10; printf("The random numbers are: %d: %f\n", i,((float) x) / 10.0)); databin[x]++;```
• 09-05-2011
laserlight
Quote:

Originally Posted by MK27
[] indicates this is a single pointer, and that is all that gets zero'd.

More accurately, the [] indicates that databins is an array whose size depends on what it was initialised with, hence it has a size (as in number of elements) of 1.
• 09-05-2011
sam.briggs
Thanks
Once again I'm indebted to you guys! Thanks! XD