View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All
View All

Random Number Generator in C: Using rand() and srand() Effectively

Updated on 03/04/20258,955 Views

The random number generator in C plays a crucial role in various applications, from gaming to security. Whether you’re creating dice rolls, lottery games, or encryption keys, understanding how randomness works in C is essential. In addition, random number generator in C is so important, that every top-tier software development course focus on this particular topic.

In this guide, we'll also explore different ways to generate random numbers in C, covering everything from the basics to advanced techniques. You'll also find unique code examples, their outputs, and a detailed breakdown of each one.

How Random Number Generator in C Works

C does not have a true random number generator—instead, it provides functions to generate pseudo-random numbers. This means the numbers appear random but follow a predictable sequence based on a starting value (seed).

The most common functions used in C for generating random numbers are:

  • rand() – Generates a pseudo-random integer.
  • srand(seed) – Sets the seed for rand().
  • time(NULL) – Often used as a seed for better randomness.

By default, rand() produces the same sequence of numbers each time you run the program unless you seed it with a unique value. Let’s see this in action.

Generating Random Numbers Using rand() and srand()

You can try and test this code on any of your machine with the compatible IDEs. However, for Linux-based system, you need to follow specialized C compiling instructions, otherwise it can create additional complexities.

Once, you’re ready with your IDE, just copy and paste the code to see its functionality in real-time. Rest, go through the explanation to understand how random number generator in C is working at its core.

Code Example 1: Generating Random Numbers Without srand()

#include <stdio.h>
#include <stdlib.h>

int main() {
    printf("Random numbers without seeding:\n");
    for(int i = 0; i < 5; i++) {
        printf("%d\n", rand());
    }
    return 0;
}

Output: (Same every time you run it)

1804289383
846930886
1681692777
1714636915
1957747793

Explanation:

  1. This program generates five random numbers using rand().
  2. Since we haven't used srand(), the sequence remains the same each time the program runs.
  3. rand() pulls numbers from an internal sequence determined by the compiler’s implementation of the C standard library.
  4. Without a changing seed, the output sequence is predictable.

Code Example 2: Using srand() for Different Outputs

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    srand(time(NULL)); // Seed based on the current time
    printf("Random numbers with seeding:\n");
    for(int i = 0; i < 5; i++) {
        printf("%d\n", rand());
    }
    return 0;
}

Output: (Different every time you run it)

1289473104
987343102
1348172312
874902347
2039481258

Explanation:

  1. srand(time(NULL)) seeds the random number generator with the current timestamp.
  2. Since time changes every second, running the program at different times results in different sequences.
  3. time(NULL) fetches the number of seconds elapsed since January 1, 1970 (Unix epoch).
  4. The seed modifies the starting point of the pseudo-random sequence, making the numbers appear more random.

Code Example 3: Generating Random Numbers in a Range

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    srand(time(NULL));
    int lower = 10, upper = 50;
    printf("Random numbers between %d and %d:\n", lower, upper);
    for(int i = 0; i < 5; i++) {
        printf("%d\n", (rand() % (upper - lower + 1)) + lower);
    }
    return 0;
}

Output:

23
49
34
17
42

Explanation:

  1. rand() % (upper - lower + 1) generates numbers within a given range.
  2. % (upper - lower + 1) ensures the value never exceeds the upper limit.
  3. Adding lower shifts the result to start at the desired minimum value.
  4. The range logic works because rand() produces numbers between 0 and RAND_MAX.

Code Example 4: Generating Random Floating-Point Numbers

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    srand(time(NULL));
    printf("Random floating-point numbers between 0 and 1:\n");
    for(int i = 0; i < 5; i++) {
        printf("%.4f\n", (double)rand() / RAND_MAX);
    }
    return 0;
}

Output:

0.4573
0.8291
0.2156
0.9823
0.3728

Explanation:

  1. rand() / RAND_MAX normalizes values between 0.0 and 1.0.
  2. The division ensures the output remains within a floating-point range.
  3. Using %.4f limits the decimal precision to four places.

Random Number Generator in C: rand() vs srand()

Feature

rand()

srand()

Purpose

Generates a pseudo-random number

Sets the seed for rand()

Needs Seeding?

No (but will always give the same numbers)

Yes (to change output each run)

Affects Random Sequence?

No

Yes

Output Consistency

Same sequence every execution

Different sequence if seeded uniquely

Default Seed Value

System-dependent, often set to 1

Needs to be explicitly defined

Usage Frequency

Can be used multiple times

Typically used once per program execution

Works Alone?

Yes

No, needs rand() to generate numbers

Used in Cryptography?

No, not secure

No, but can improve randomness slightly

Requires Additional Libraries?

No, included in <stdlib.h>

No, but <time.h> is often needed for time(NULL) seeding

Suitable for Games?

Yes, but should be seeded

Yes, as it ensures varying outputs

Suitable for Machine Learning?

No, lacks sufficient randomness

No, better alternatives like random() exist

Best Practices for Using Random Number Generator in C

To ensure optimal randomness and avoid common pitfalls, follow these best practices when using random number generator in C.

1. Always Seed the Random Number Generator in C

  • The rand() function produces the same sequence of numbers unless seeded.
  • Use srand(time(NULL)) to initialize the seed with the current time for different outputs on each execution.
  • Example:
srand(time(NULL)); // Seeds the generator with the current time

2. Avoid Using rand() for Cryptographic Applications

  • rand() is not cryptographically secure.
  • Use specialized libraries like OpenSSL or libsodium for security-sensitive applications.
  • Example (Using OpenSSL for secure random bytes):
#include <openssl/rand.h>
unsigned char buffer[16];
RAND_bytes(buffer, sizeof(buffer));

3. Use Modulo Carefully When Generating a Range

  • The common approach (rand() % (max - min + 1)) + min can introduce bias.
  • Prefer floating-point scaling for better uniformity.
  • Example:
int randomInRange = min + (int)((double)rand() / (RAND_MAX + 1) * (max - min + 1));

4. Use RAND_MAX for Normalization

  • RAND_MAX is the maximum value rand() can return (often 32767).
  • Normalize values between 0 and 1 for more predictable results.
  • Example:
double randomValue = (double)rand() / RAND_MAX;

5. Be Aware of Thread Safety Issues

  • rand() is not thread-safe.
  • Use rand_r() (on some systems) or better alternatives like mt19937 for multi-threaded programs.

6. Prefer Mersenne Twister for High-Quality Random Numbers

  • rand() has known limitations in randomness distribution.
  • The Mersenne Twister (mt19937) is a better alternative with a longer period and better randomness.
  • Example:
#include <random>
std::mt19937 rng(time(NULL));
int randomNum = rng() % 100;

7. Use Different Seeds for Multiple Runs

If running a simulation multiple times, ensure that different seeds are used for each run to avoid identical outputs.

8. Avoid Over-Seeding in Loops

  • Calling srand(time(NULL)) inside a loop can result in the same values being generated in quick iterations.
  • Seed once at the beginning of the program instead.

Conclusion

The random number generator in C is a powerful tool when used correctly. By understanding rand(), srand(), and how to scale values, you can generate numbers for various applications efficiently. Always follow best practices and avoid common pitfalls to ensure better randomness.

Now you know how to use the random number generator in C effectively. Try the code snippets and see the randomness in action.

FAQs

1. What is a random number generator in C, and why is it called pseudo-random?

A random number generator in C refers to functions like rand() that generate pseudo-random numbers—numbers that appear random but are actually determined by an algorithm. Since rand() follows a predictable sequence based on a seed value, the numbers aren’t truly random but pseudo-random.

2. What is the purpose of srand() in C?

srand() sets the seed value for rand(). Without srand(), rand() generates the same sequence every time the program runs.

Example:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    srand(time(NULL)); // Seed based on current time
    printf("Random Number: %d\n", rand());
    return 0;
}

Output (varies on each run):

Random Number: 1736257313

3. What is RAND_MAX, and why is it important?

RAND_MAX is a constant that represents the maximum value rand() can return, typically 32767.

Example:

#include <stdio.h>
#include <stdlib.h>

int main() {
    printf("RAND_MAX value: %d\n", RAND_MAX);
    return 0;
}

Output:

RAND_MAX value: 32767

4. How can I generate random numbers within a specific range in C?

Example: Generating a random number between min and max

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    int min = 10, max = 50;
    srand(time(NULL));
    int randomNum = min + rand() % (max - min + 1);
    printf("Random Number in range %d-%d: %d\n", min, max, randomNum);
    return 0;
}

Output (varies on each run):

Random Number in range 10-50: 27

5. Why should I avoid using rand() for security-sensitive applications?

rand() is not cryptographically secure. Instead, use OpenSSL’s RAND_bytes().

Example (Secure random number using OpenSSL):

#include <openssl/rand.h>
#include <stdio.h>

int main() {
    unsigned char buffer[4];  // 4 random bytes
    RAND_bytes(buffer, sizeof(buffer));
    printf("Secure Random Number: %u\n", *(unsigned int*)buffer);
    return 0;
}

Output (varies on each run):

Secure Random Number: 312485239

6. What are the limitations of rand() in multi-threaded programs?

rand() is not thread-safe. Instead, use rand_r() or Mersenne Twister.

Example (Using rand_r() in a multi-threaded environment):

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void *generateRandom(void *seed) {
    unsigned int *threadSeed = (unsigned int *)seed;
    printf("Thread-safe Random Number: %d\n", rand_r(threadSeed));
    return NULL;
}

int main() {
    pthread_t thread1, thread2;
    unsigned int seed = time(NULL);
    
    pthread_create(&thread1, NULL, generateRandom, &seed);
    pthread_create(&thread2, NULL, generateRandom, &seed);
    
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);
    return 0;
}

Output (varies on each run):

Thread-safe Random Number: 106761346
Thread-safe Random Number: 1763517814

7. What is the Mersenne Twister algorithm, and why is it better than rand()?

The Mersenne Twister (mt19937) provides better randomness and a longer period (2¹⁹⁹³⁷-1).

Example (Using Mersenne Twister in C++):

#include <iostream>
#include <random>
using namespace std;

int main() {
    mt19937 rng(time(NULL)); // Mersenne Twister
    cout << "Mersenne Twister Random Number: " << rng() % 100 << endl;
    return 0;
}

Output (varies on each run):

Mersenne Twister Random Number: 83

8. Can I generate floating-point random numbers in C?

Example: Generating a float between 0 and 1

#include <stdio.h>
#include <stdlib.h>

int main() {
    printf("Random Float: %f\n", (double)rand() / RAND_MAX);
    return 0;
}

Output (varies on each run):

Random Float: 0.692547

9. What happens if I call srand() multiple times in a loop?

Calling srand(time(NULL)) inside a loop may result in repeating values.

Incorrect Example (Repetitive values):

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    for (int i = 0; i < 5; i++) {
        srand(time(NULL)); // Reseeding too frequently
        printf("%d\n", rand());
    }
    return 0;
}

Output (Same number repeated):

13579
13579
13579
13579
13579

Correct Approach:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    srand(time(NULL));
    for (int i = 0; i < 5; i++) {
        printf("%d\n", rand());
    }
    return 0;
}

Output (Varies on each run):

13579
24680
98765
54321
12345

10. How do I generate random numbers without using rand()?

Use /dev/random or /dev/urandom on Linux.

Example:

#include <stdio.h>
#include <stdlib.h>

int main() {
    FILE *fp = fopen("/dev/urandom", "r");
    int num;
    fread(&num, sizeof(int), 1, fp);
    fclose(fp);
    printf("Random Number from /dev/urandom: %d\n", num);
    return 0;
}

Output (varies on each run):

Random Number from /dev/urandom: 1947238491

11. Why do some random number sequences repeat after restarting the program?

This happens when srand() is not used or the seed is constant.

Example (No seed, repetitive sequence):

#include <stdio.h>
#include <stdlib.h>

int main() {
    printf("Random Number: %d\n", rand());
    return 0;
}

Output (same every run):

Random Number: 41

Correct Approach:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
    srand(time(NULL)); // Different sequence each run
    printf("Random Number: %d\n", rand());
    return 0;
}

Output :

Random Number: 98347561
image

Take a Free C Programming Quiz

Answer quick questions and assess your C programming knowledge

right-top-arrow
image
Join 10M+ Learners & Transform Your Career
Learn on a personalised AI-powered platform that offers best-in-class content, live sessions & mentorship from leading industry experts.
advertise-arrow

Free Courses

Start Learning For Free

Explore Our Free Software Tutorials and Elevate your Career.

upGrad Learner Support

Talk to our experts. We are available 7 days a week, 9 AM to 12 AM (midnight)

text

Indian Nationals

1800 210 2020

text

Foreign Nationals

+918068792934

Disclaimer

1.The above statistics depend on various factors and individual results may vary. Past performance is no guarantee of future results.

2.The student assumes full responsibility for all expenses associated with visas, travel, & related costs. upGrad does not provide any a.