0

If I do rand()/RAND_MAX, will it give me a random probability value?

If I do so, is it going to be that 50% (on average) of the values will be more than 0.5?

Mark Adler
  • 101,978
  • 13
  • 118
  • 158
gag123
  • 357
  • 1
  • 2
  • 8

2 Answers2

4

Never use rand() for any purpose, ever.

random() is likely suitable for your needs. (#include <stdlib.h>) It generates a uniform distribution in the range 0..231-1. random() / (double)((1L << 31) - 1) should get you close to a uniform distribution between 0.0 and 1.0.

You can use srandomdev() to seed it in order to get a different sequence every time.

Here is a histogram of one billion values returned by random() in 256 bins over the range 0..231-1:

uniform

If you look closely, you can see the expected tiny variations from uniform along the top of the histogram.

Mark Adler
  • 101,978
  • 13
  • 118
  • 158
  • I do not see any mention of a distribution in my man pages, nor in the POSIX manual. Can you elaborate on the function distribution? – user14063792468 Mar 22 '21 at 06:04
  • 1
    It should say that explicitly, but it is both expected for any such random number generator, as well as implicit in the generation of pseudo-random numbers using these overflow/modulo arithmetic approaches. All possible values in the range are equally accessible to the sequence. – Mark Adler Mar 22 '21 at 06:27
  • So the sequence is uniformly distributed? – user14063792468 Mar 22 '21 at 07:40
  • @user14063792468 the picture shows **one billion** values, I would consider it uniform enough, and can produce only 2^31 distinct values but in any case would be much better than `rand()` which is guaranteed to only produce 2^15 distinct values. – Antti Haapala -- Слава Україні Mar 22 '21 at 07:48
  • @user14063792468 See histogram. – Mark Adler Mar 22 '21 at 19:40
  • @MarkAdler Sure, looks uniform. BTW, thanks for sparing a time to produce one. – user14063792468 Mar 22 '21 at 19:48
  • @MarkAdler Is it `FreeBSD` or `Linux`? I`m asking because if the histogram is a Linux one, I bet on it to get some uniform distribution. – user14063792468 Mar 22 '21 at 19:55
  • macOS. Just as uniform on Linux, FreeBSD, NetBSD, OpenBSD. – Mark Adler Mar 22 '21 at 22:56
  • note that those bin counts (should be) Poisson distributed with mean=1e9/256. given that they are around 600 pixels high, the expected variance would around 2 pixels (i.e. `round(qpois(c(1,255)/256, mu) / mu*600)` in R), which looks right to me. – Sam Mason Mar 23 '21 at 12:57
  • Since the mean is so large, the Poisson distribution is very closely approximated by a Gaussian distribution whose mean and variance is equal to the mean of the Poisson. Then if I compute the standard deviation of the 256 bins, I should get something close to the square root of the mean, which is 1976. Indeed, when I compute the standard deviation of the bins in the histogram above, I get 2029. – Mark Adler Mar 23 '21 at 17:13
1
  1. Yes the rand() / (double)RAND_MAX will give you a random value.
  2. No, rand() have no mention of a uniform(or any other) distribution. There is no guarantee that "is it going to be that 50% (on average)".

Have a uniform distribution in C is a different question. You may be interested in Generating a uniform distribution of INTEGERS in C SO topic.

user14063792468
  • 839
  • 12
  • 28
  • 1
    note that it's generally a requirement that (P)RNGs be uniformly distributed. i.e. each bit be true with probability 0.5 and all independent of each other. exceptions tend to be called out, for example with [xoshiro256+](https://prng.di.unimi.it/) this isn't true for the low order bits, but these bits are discarded when used as it's been designed so worth it for the performance win – Sam Mason Mar 23 '21 at 13:12
  • @SamMason Honestly, really, I do not knew it. – user14063792468 Mar 23 '21 at 13:54