# Thread: Issue with Filling Array

1. ## 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;
}
}

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.

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

3. 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'

4. Thank you so much! Its kind of just clicked in my head! XD

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

6. That's because
Code:
`int databins[] = {0};`
creates a one not ten element array.

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

8. 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]++;```

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

10. ## Thanks

Once again I'm indebted to you guys! Thanks! XD