Why are drand48 () and friends out of date?

In the end, they seem to be above the standard libc rand (). Did I miss something?

(I spent some time searching for this online, and the only other instance of this question that I could find was in the context of the distribution bias and went unanswered.)

The manual pages for rand () and drand48 () also seem to be mismatched. The first recommends the second, and the second claims that it is outdated and should be used first. (Although, to be fair, many people who understand the math behind PRNG have problems with man pages for these functions because they are poorly worded and in some cases are simply wrong.)

However, I can not find excuses for the "obsolete" status.

+7
c posix random obsolete
source share
2 answers

The man page on my system (which from the man project of the man pages says:

These functions are deprecated by SVID 3, which states that rand(3) should be used instead.

SVID 3 was published in 1989.

SVID 4 (link to 720-page PDF), published in 1995, documents drand48 , erand48 , lrand48 , nrand48 , mrand48 , jrand48 , srand48 , seed48 and lcong48 and, like POSIX, do not say anything that they are outdated.

POSIX , since 2013, does not say anything that they are out of date, out of date or out of date.

I did not find a copy of SVID 3, so I don’t know why it would declare these functions obsolete, but apparently this solution was revised later. The statement on the manual page looks like outdated information. I would not worry about that.

As for the function you should use, the C rand() function is the most portable (unless you recompile another version from the source code). Some rand() implementations are of poor quality, with the low-order bit being repeated in a very correct pattern; others are a little better.

If you don't need high-quality pseudo-random numbers, you can also use rand() (seeded by calling srand() with a reasonable value, like srand(time(NULL)) .

If you need high-quality pseudo-random numbers, it is likely that none of these functions will be good enough, I would advise, for example, to use any of them for cryptography. You can use /dev/urandom or /dev/random if your system supports it. I heard good things about Mersenne Twister , but I don't have enough experience to comment.

(By the way, if you are searching in SVID for SVID, watch out for Svið ).

+6
source share

Standards Note:

  • rand() is part of the C standard, so it should be provided. Its implementation is not defined, 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. His algorithm seems to be indicated, he should use a 48-bit linear congruent 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 status words and an unspecified algorithm, according to man 3 random :

    The random () function uses a random number generator with non-linear incremental feedback, using the default table for long integers of size 31 to return consecutive pseudorandom numbers ranging 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. Best of all 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 congruent) with a relatively small number of states (48 bits), so it should be avoided. None of the random number generators discussed here is suitable for, for example, Monte Carlo, but drand48() is probably much worse than rand() or random() .

Which should i use?

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

I usually avoided rand() because on many systems it is a bad generator, often a linear congruent 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() fine.

I would use random() on any POSIX system if I needed random numbers, but it really didn't matter to me how they were generated.

You can always use your own random number generator: if you want to create 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.

+2
source share

All Articles