Why are drand48() and friends obsolete?

后端 未结 2 805
萌比男神i
萌比男神i 2021-01-12 00:22

After all, they seem superior to the standard libc rand(). Have I missed something?

(I have spent some time searching for this online, and the only other instance of

2条回答
  •  北海茫月
    2021-01-12 00:55

    A note about standards:

    • rand() is part of the C standard, so it must be provided. Its implementation is unspecified, but in glibc, it uses the same algorithm as random(). From man 3 rand:

      The versions of rand() and srand() in the Linux C Library use the same random number generator as random(3) and srandom(3),...

    • drand48() is part of the POSIX standard. Its algorithm appears to be specified, it must use a 48-bit linear congruential generator with the following formula (according to man 3 drand48):

         Xn+1 = (aXn + c) mod m, where n >= 0
      
    • random() is part of the POSIX standard. It uses 31 words of state and an unspecified algorithm, according to man 3 random:

      The random() function uses a nonlinear additive feedback random number generator employing a default table of size 31 long integers to return successive pseudo-random numbers in the range from 0 to RAND_MAX. The period of this random number generator is very large, approximately 16 * ((2^31) - 1).

    So, POSIX has these three random number generators. The best one is random() or rand(), which are the same in glibc (but probably not the same on other systems). The drand48() generator is a very simple type (linear congruential) with a relatively small amount of state (48 bits) so it should be avoided. None of the random number generators discussed here are necessarily suitable for e.g. Monte Carlo simulation, but drand48() is probably much worse than rand() or random().

    Which one should I use?

    I would always avoid drand48() because it is a tiny little linear congruential generator with a small state, and it is only available on POSIX systems. On POSIX systems, random() is usually available, and is better.

    I would usually avoid rand() because on many systems it is a poor generator, often a linear congruential generator that is even smaller than drand48(), and its least significant bits on some systems are cyclical. If you don't need good random numbers, then rand() is fine.

    I would use random() on any POSIX system if I needed random numbers but didn't care very deeply about how they are generated.

    You can always use your own random number generator: if you want a good, portable random number generator, this is your only choice. Mersenne Twister has been a popular choice in the past, although smaller generators seem to be popular these days.

提交回复
热议问题