Search code examples
calgorithmrandomplatform

What common algorithms are used for C's rand()?


I understand that the C specification does not give any specification about the specific implementation of rand(). What different algorithms are commonly used on different major platforms? How do they differ?


Solution

  • See this article: http://en.wikipedia.org/wiki/List_of_random_number_generators

    This is the source code of glibc's rand():

    /* Reentrant random function from POSIX.1c.
       Copyright (C) 1996, 1999, 2009 Free Software Foundation, Inc.
       This file is part of the GNU C Library.
       Contributed by Ulrich Drepper <[email protected]>, 1996.
    
       The GNU C Library is free software; you can redistribute it and/or
       modify it under the terms of the GNU Lesser General Public
       License as published by the Free Software Foundation; either
       version 2.1 of the License, or (at your option) any later version.
    
       The GNU C Library is distributed in the hope that it will be useful,
       but WITHOUT ANY WARRANTY; without even the implied warranty of
       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       Lesser General Public License for more details.
    
       You should have received a copy of the GNU Lesser General Public
       License along with the GNU C Library; if not, write to the Free
       Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
       02111-1307 USA.  */
    
    #include <stdlib.h>
    
    
    /* This algorithm is mentioned in the ISO C standard, here extended
       for 32 bits.  */
    int
    rand_r (unsigned int *seed)
    {
      unsigned int next = *seed;
      int result;
    
      next *= 1103515245;
      next += 12345;
      result = (unsigned int) (next / 65536) % 2048;
    
      next *= 1103515245;
      next += 12345;
      result <<= 10;
      result ^= (unsigned int) (next / 65536) % 1024;
    
      next *= 1103515245;
      next += 12345;
      result <<= 10;
      result ^= (unsigned int) (next / 65536) % 1024;
    
      *seed = next;
    
      return result;
    }
    

    Source: https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=stdlib/rand_r.c;hb=HEAD

    As you can see, it's simply multiply with an addition and a shift. The values are carefully chosen to make sure that you get no repeat of the output for RAND_MAX iterations.

    Note that this is an old implementation which has been replaced by a more complex algorithm: https://sourceware.org/git/?p=glibc.git;a=blob_plain;f=stdlib/random_r.c;hb=HEAD

    If the link if broken, Google for "glibc rand_r"