Reputation:
I wrote the following piece of code to generate random numbers in c++
#include <stdlib.h>
#include <iostream>
#include <ctime>
#define ARRAY_SIZE 5
#define MAX_VAL ARRAY_SIZE*5+1
int main() {
srand(time(NULL));
int arr [ARRAY_SIZE];
for (int i = 0; i < ARRAY_SIZE; i++) {
arr[i] = (rand() % MAX_VAL);
}
for (int i = 0; i < ARRAY_SIZE; i++) {
printf ("%d\n", arr[i]);
}
return 0;
}
When I run this I get almost identical numbers each time:
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
11
16
16
21
16
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
21
11
21
11
6
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
6
6
1
16
6
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
16
1
16
6
21
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
1
21
21
11
21
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
1
21
21
11
21
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
11
16
1
1
11
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
11
16
1
1
11
tyler@Tylers-MacBook-Pro hw2 % ./MergeSort
21
1
6
6
1
Why is my random number generator only giving me the values: 1, 6, 11, 16 and 21? This makes no sense to me. I made sure to seed it and the numbers aren't always in the same order which is what makes this even more confusing. As a side note I am using OSX.
Upvotes: 0
Views: 103
Reputation: 27633
The problem is that MAX_VAL
is defined as ARRAY_SIZE*5+1
, not (ARRAY_SIZE*5+1)
. This means that your use in arr[i] = (rand() % MAX_VAL);
expands to:
arr[i] = (rand() % 5 * 5 + 1);
There aren't a lot of options (only 5 possibilities), which is why you're seeing the same numbers. You can fix this by parenthesizing the definition of MAX_VAL
or making it a contant variable:
const unsigned int MAX_VAL = ARRAY_SIZE * 5 + 1;
A secondary issue is the use of srand(time(NULL))
. On most systems, time
will return the same value if the program is run in the same second. This means running the program in rapid succession (within the same second) will yield the same results. It is preferable to use the PRNG facilities in <random>
.
Upvotes: 6
Reputation: 211560
Others have pointed out the two primary issues in this code, but it's worth showing the C++ way of doing things here for contrast and to un-learn a lot of the C thinking that broke this code in the first place.
The C++ version of this code side-steps a lot of the problems here by using facilities C++ has and C lacks:
#include <random>
#include <vector>
#include <iostream>
int main() {
// Define constants instead of using #define, as this avoids interpolation syntax issues
const size_t array_size = 5;
const int max = array_size * 5 + 1;
// Use the C++ random number generator facilities
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> dis(0, max);
// Use a dynamically sized array
std::vector<int> arr;
for (int i = 0; i < array_size; ++i) {
arr.push_back(dis(gen));
}
// Use C++ container iteration to simplify code
for (const int& i : arr) {
// Use streams for output
std::cout << i << std::endl;
}
return 0;
}
Upvotes: 1
Reputation: 123
This is because of your using of #define MAX_VAL
The actual calculation is rand() % 5 * 5 + 1
, which means, you first modulo the rand() result with 5, and then multiple by 5, and then add 1.
I assuming you mean to write rand () % (5 * 5 + 1)
That can be resolved by:
#define MAX_VAL (ARRAY_SIZE * 5 + 1)
Upvotes: 0