5

In general, when I need to generate a random value within a closed interval (considering B as the beginning and E as the end of the interval) in C, I use one of the following approaches:

Approach 1:

n = round(B + ( (float)rand() / RAND_MAX ) * (E - B)); 

Approach 2:

n = B + rand()%(E - B+1); 

Both of them consider the initialization of the random seed with the function time():

srand(time(NULL)); 

In Linux systems, both approaches seem good enough for generating interesting random values. However, in Windows systems, sometimes the numbers do not appear to be random enough.

Investigating these systems, I've found that the value of RAND_MAX is different. In the Linux systems that I have tested RAND_MAX is 2147483647. In these windows systems with a not-so-good behavior, RAND_MAX is 32767.

I think that with a larger RAND_MAX value we can generate better random numbers. But I'm not sure.

With this in mind, my question is: Is there some good way of generating interesting random numbers (within a closed interval) that work well on all systems?

Besides that, my approaches 1 and 2 are good approaches for generating random numbers within a closed interval?

9
  • 3
    Personally, I use PCG for high quality pseudo random numbers; the C implementation has a routine for uniform numbers in a range Commented Oct 1, 2021 at 0:56
  • 5
    OP: See stackoverflow.com/q/10984974/9952196 for why using % is a not ideal approach. Commented Oct 1, 2021 at 1:01
  • 5
    “Best” is a matter of opinion, and there are several issues you have not addressed in your question. First, either rand() / something or rand() % something is non-uniform—the number of values rand generates is usually not a multiple of the number of values in your target set. So some elements of the target set will be generated more often than others. The difference may be slight, but certainly the best way to generate random numbers would have zero difference. Will E-B ever be more than a small fraction of RAND_MAX? The greater it is, the greater the non-uniformity will be. Commented Oct 1, 2021 at 1:06
  • 2
    State of the art: Lemire, Daniel. "Fast random integer generation in an interval." ACM Transactions on Modeling and Computer Simulation (TOMACS) 29, no. 1 (2019): 1-12 Commented Oct 1, 2021 at 8:52
  • 2
    The round method in the question generates the endpoints with about half the frequency of other points. Values for the division that are in [0, ½)/(E−B) will yield a final result of B, while values in [½, 1½)/(E−B) will yield a final result of B+1. The latter interval is twice the former, and all the interior points have an interval of that length. Then the final interval is [E−B−½, E−B]/(E−B), which is back to about half of the interior intervals. Is that what you want? Commented Oct 1, 2021 at 11:47

0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.