How can I generate random integers without bias using programming?

In summary, the conversation discusses the use of srand() and the rand() function in generating random integers. It is clarified that srand() is used only to seed the random number generator and does not return a value. The rand() function, on the other hand, returns an integer value within a specific range, which can be modified using the modulus operator. However, this method may not produce a truly random distribution and alternative approaches are suggested for more accurate results. Additionally, the use of doubles over ints for storing a wider range of integers is also mentioned.
  • #1
leroyjenkens
616
49
In my book, it says the way to produce a random integer from, for example, 1-50 is to use srand() % 50 + 1.
But wouldn't that give "1" the chance of showing up more often than other numbers?
If srand is 0, then the random result is 1. If srand is 50, then the random result is also 1. The other numbers only have one chance of showing up, while "1" has two. Or am I missing something?

Thanks.
 
Technology news on Phys.org
  • #2
Yes, you are missing something, or rather, a couple of things. One, srand is used only to seed the random number generator. It doesn't return a value. To generate a random number, use the rand function, which returns an int value.

Two, assuming that an int is 32 bits, the rand function will return a value in the range -2147483648 through +2147483647 inclusive. Applying the modulus operator gives you a number in the range 0 through 49. Adding 1 gives you a number in the range 1 through 50. For each of the numbers 0 through 49, there are lots of possible outputs of rand() % 50 that produce it. For example, rand() could produce ... -99, -49, 1, 51, 101, 151, 201, ..., and rand() % 50 would evaluate to 1.
 
  • #3
Mark44 said:
Two, assuming that an int is 32 bits, the rand function will return a value in the range -2147483648 through +2147483647 inclusive.

The C++ specification says rand() returns a number between 0 and RAND_MAX, which may be as small as 32767.

Just taking the modulus will not give a truly random distribution. if RAND_MAX was 32767, there would be is a slight bias in favor of numbers between 0 and 17. Think what happens if the random number is between 32750 and 32767.

For anything serious, don't use the rand() library function anyway - you don't know what its properties are, and they are different for different implementations of the standard library. Find a good quality RNG that produces floating point numbers r with ##0 \le r \lt 1##, and then do (int)(r*50) + 1
 
  • #4
A good quality RNG that produces integers is just as good as one that produces floating point. Probably better, due to greater precision.

In any case, if your RNG has a small range and you are worried about edge effects, there are a couple of things you can do:

You could sample with rejection. e.g. if your RNG produces numbers in [0, 32767], you could use the algorithm
Code:
int rand50() {
    while(1) {
        int x = rand();
        if(x < 32750) { return x % 50 + 1; }
    }
}
(replace rand() with whatever rng you want)

You could aggregate several values together to diminish the effects. e.g.
Code:
int rand50() {
    while(1) {
        uint32_t x = rand();
        uint32_t y = rand();
        uint32_t z = (x * 32768) + y;
        return z % 50 + 1;
    }
}
(replace rand() with whatever rng you want)
 
  • #5
Hurkyl said:
A good quality RNG that produces integers is just as good as one that produces floating point. Probably better, due to greater precision.

The precision may be irrelevant here, because taking the modulus is homing in on the low-order bits of the integer. For example in the OP's case, whether the modulus creates an odd or even number depends only on ONE bit of the 32-bit integer. There may be an unwanted pattern of "odds and evens" in the sequence of random numbers, even if each number has equal probabilty of occurring.

Dividing the whole range of the RNG into N intervals avoids that problem. At worst, it homes in on the the high-order bits rather that the low-order, and that is less likely to behave badly.

In any case, for a 32-bit C implementation with IEEE arithmetic, a double can store a wider range of integers exactly (up to 2^52) than an int.
 
  • #6
AlephZero said:
The precision may be irrelevant here, because taking the modulus is homing in on the low-order bits of the integer. For example in the OP's case, whether the modulus creates an odd or even number depends only on ONE bit of the 32-bit integer. There may be an unwanted pattern of "odds and evens" in the sequence of random numbers, even if each number has equal probabilty of occurring.
What you are reacting to is a specific deficiency of certain types of low-quality random number generators -- e.g. a Linear Congruential Generator (LCG) with power-of-2 modulus.

But whether the result is even or odd will always be determined by a single bit of information about the random number. And for a high-quality RNG, simply taking the low bit will have exactly the same quality as any other practical method of using it to decide between 0 and 1.
In any case, for a 32-bit C implementation with IEEE arithmetic, a double can store a wider range of integers exactly (up to 2^52) than an int.
I honestly don't remember the last time I programmed in a C/C++ environment that didn't have a 64-bit integer type available.
 
  • #7
Hurkyl said:
What you are reacting to is a specific deficiency of certain types of low-quality random number generators -- e.g. a Linear Congruential Generator (LCG) with power-of-2 modulus.
Sure, but several widely used C implementations use exactly that, according to Wikipedia. A quick and simple LCG is perfectly adequate for many purposes provided you use it the right way. IMO the OP's book is the wrong way. Usinng the standard library rand(), a better way is
Code:
r = (int)(rand()/(RAND_MAX + 1.0)) * 50 + 1;
With a more sophisticated RNG that might not be necessary, but the defensive programming does no harm.
 

What are random integers in programming?

Random integers are numbers that are generated by a computer program using a random number generator. These numbers are not predetermined and are selected from a range of possible values.

Why do we use random integers in programming?

Random integers are used in programming for a variety of purposes. They can be used for creating random events or outcomes in games, generating unique codes or passwords, and for statistical simulations.

How do you generate random integers in programming?

There are various ways to generate random integers in programming. One method is to use a built-in random number generator function, such as the "rand()" function in C++, which generates a random number between 0 and a specified maximum value. Another method is to use a third-party library or API that specializes in random number generation.

What is the difference between random integers and pseudo-random integers?

Random integers are truly random and cannot be predicted or reproduced, while pseudo-random integers are generated using algorithms that produce numbers that appear random but are actually determined by a starting value called a seed. Pseudo-random integers are used in situations where true randomness is not necessary, such as in simulations or games.

How can you ensure that random integers are truly random?

To ensure that random integers are truly random, it is important to use a high-quality random number generator and to properly seed the generator with a value that is difficult to predict. Additionally, using a large range of possible values and avoiding patterns in the numbers can help increase the randomness of the generated integers.

Similar threads

  • Programming and Computer Science
Replies
1
Views
627
  • Programming and Computer Science
Replies
19
Views
2K
  • Programming and Computer Science
Replies
9
Views
2K
  • Programming and Computer Science
Replies
11
Views
1K
  • Programming and Computer Science
Replies
8
Views
872
Replies
9
Views
1K
  • Programming and Computer Science
Replies
6
Views
2K
Replies
25
Views
3K
  • Programming and Computer Science
Replies
2
Views
967
Replies
5
Views
2K
Back
Top