Thread: Issue with Filling Array

  1. #1
    Registered User
    Join Date
    Aug 2011
    Posts
    11

    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.

  2. #2
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by sam.briggs View Post
    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
    Last edited by MK27; 08-30-2011 at 06:57 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  3. #3
    Registered User rogster001's Avatar
    Join Date
    Aug 2006
    Location
    Liverpool UK
    Posts
    1,472
    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'
    Thought for the day:
    "Are you sure your sanity chip is fully screwed in sir?" (Kryten)
    FLTK: "The most fun you can have with your clothes on."

    Stroustrup:
    "If I had thought of it and had some marketing sense every computer and just about any gadget would have had a little 'C++ Inside' sticker on it'"

  4. #4
    Registered User
    Join Date
    Aug 2011
    Posts
    11
    Thank you so much! Its kind of just clicked in my head! XD

  5. #5
    Registered User
    Join Date
    Aug 2011
    Posts
    11
    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. #6
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    That's because
    Code:
    int databins[] = {0};
    creates a one not ten element array.

  7. #7
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    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.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  8. #8
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    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. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    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.
    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

  10. #10
    Registered User
    Join Date
    Aug 2011
    Posts
    11

    Thanks

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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. filling a char array
    By steve1_rm in forum C Programming
    Replies: 3
    Last Post: 03-02-2009, 02:41 AM
  2. Filling up a 2D (or 3D) array.
    By omnificient in forum C Programming
    Replies: 1
    Last Post: 01-20-2008, 01:22 PM
  3. Filling an array
    By GCNDoug in forum C Programming
    Replies: 18
    Last Post: 04-25-2007, 02:46 PM
  4. Filling an array
    By nizbit in forum C Programming
    Replies: 3
    Last Post: 01-23-2005, 02:02 PM
  5. filling an array
    By Flex in forum C Programming
    Replies: 7
    Last Post: 02-28-2002, 03:11 PM

Tags for this Thread