Should I use rand N or rand / RAND_MAX / N 1?
Data Structures & Algorithms practice on Codemia
Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.
In the realm of programming, generating random numbers is a critical task for numerous applications, ranging from simulations to gaming and cryptography. While languages like C and C++ provide functions like `rand()`, ensuring the randomness and uniformity of the generated numbers requires a good understanding of how to scale and use the output effectively.
This article compares two popular methods to generate random numbers within a specific range using C/C++: `rand() % N` and `rand() / (RAND_MAX / N + 1)`.
Understanding `rand()`
The `rand()` function generates a pseudo-random integer between `0` and `RAND_MAX`, where `RAND_MAX` is a constant defined in the `stdlib.h` header, typically with a value of at least `32767`. Given that `rand()` often has a bounded range determined by `RAND_MAX`, scaling this to any arbitrary range `(0, N-1)` becomes a central question.
Method 1: `rand() % N`
The expression `rand() % N` is perhaps the most straightforward method to generate a number within the range `0` to `N-1`. Here, the modulus operator `%` is used to wrap around the sequence of integers produced by `rand()`.
Pros and Cons
- Pros:
- Simplicity: Easy to implement and understand.
- Efficiency: Performs faster due to minimal computational overhead.
- Cons:
- Non-uniform Distribution: If `RAND_MAX + 1` is not an exact multiple of `N`, this method will produce some numbers more frequently than others. This can lead to a bias known as "modulo bias".
- Limited Range: May not utilize the full precision available in the generated random value.
Example
- Pros:
- Uniform Distribution: Reduces or eliminates bias by scaling the numbers more evenly across the range.
- Cons:
- Complexity: Slightly more tricky to implement and can be a bit more computationally expensive due to division.
- Potential Overhead: Requires floating-point operations which might be less performant, especially in systems with limited floating-point computation power.
Related reading
- Should one prefer STL algorithms over hand-rolled loops?
- Should sorting algorithm pass same element in the comparison function
- Should we used k-means instead of k-means?
- shuffle rearrange randomly a Liststring
- Shuffle string c
- Shuffling algorithm analysis
- SICP example Counting change, cannot understand
- Sieve of Eratosthenes algorithm in JavaScript running endless for large number

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseData Structures & Algorithms practice on Codemia
Step through 300+ coding interview problems with animated visualisers that show the data structure changing as the code runs. The Blind 75 are free.