How to generate random long int in C where every digit is non-zero? Moreover the random numbers are repeating

Khushit Shah Source

I am making a library management in C for practice. Now, in studentEntry I need to generate a long int studentID in which every digit is non-zero. So, I am using this function:

long int generateStudentID(){
    srand(time(NULL));     
    long int n = 0;
    do
    {
        n = rand() % 10;
    }while(n == 0);
    int i;     
    for(i = 1; i < 10; i++)
    {
        n *= 10; 
        n += rand() % 10;
    }
    if(n < 0)
        n = n * (-1); //StudentID will be positive
    return n;
}

output

Name : khushit
phone No. : 987546321
active : 1
login : 0
StudentID : 2038393052
Wanted to add another student?(y/n)

I wanted to remove all zeros from it. Moreover, when I run the program the first time the random number will be the same as above, and second time random number is same as past runs like e.g:-

program run 1

StudentID : 2038393052
StudentID : 3436731238

program run 2

StudentID : 2038393052
StudentID : 3436731238

What do I need to fix these problems?

crandomintlong-integer

Answers

answered 5 months ago gchen #1

Slightly modify the order of your original function should perform the trick. Instead of removing 0s, just do not add 0s.

long int generateStudentID(){
         srand(time(NULL));             
         long int n = 0;         
         for(int i = 0; i < 10; i++)
         {
            long int m = 0;
            do
            {
                m = rand() % 10;
            }while(m == 0);
             n *= 10; 
             n += m;
         }
        //Not needed as n won't be negative
        //if(n < 0)
        //n = n * (-1); //StudentID will be positive
        return n;
    }

answered 5 months ago deamentiaemundi #2

You can either do as gchen suggested and run a small loop that continues until the result is not zero (just like you did for the first digit) or accept a small bias and use rand() % 9 + 1.

The problem with the similar sequences has its reason with the coarse resolution of time(). If you run the second call of the function to fast after the first you get the same seed. You might read this description as proposed by user3386109 in the comments.

answered 5 months ago Jonathan Leffler #3

A nine-digit student ID with no zeros in the number can be generated by:

long generateStudentID(void)
{
    long n = 0;
    for (int i = 0; i < 9; i++)
        n = n * 10 + (rand() % 9) + 1;
    return n;
}

This generates a random digit between 1 and 9 by generating a digit between 0 and 8 with (rand() % 9) and adding 1. There's no need to for loops to avoid zeros.

Note that this does not call srand() — you should only call srand() once in a given program (under normal circumstances). Since a long must be at least 32 bits and a 9-digit number only requires 30 bits, there cannot be overflow to worry about.

It's possible to argue that the result is slightly biassed in favour of smaller digits. You could use a function call to eliminate that bias:

int unbiassed_random_int(int max)
{
    int limit = RAND_MAX - RAND_MAX % max;
    int value;
    while ((value = rand()) >= limit)
        ;
    return value % max;
}

If RAND_MAX is 32767 and max is 9, RAND_MAX % 9 is 7. If you don't ignore the values from 32760 upwards, you are more likely to get a digit in the range 0..7 than you are to get an 8 — there are 3642 ways to each of 0..7 and only 3641 ways to get 8. The difference is not large; it is smaller if RAND_MAX is bigger. For the purposes on hand, such refinement is not necessary.

comments powered by Disqus