1 /* Copyright (C) 1995, 1996, 1997, 1998, 2001 Free Software Foundation, Inc.
2    This file is part of the GNU C Library and the VMIPS testsuite.
3    Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, August 1995.
4 
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9 
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14 
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18    MA 02110-1301, USA.  */
19 
20 /* (brg) This file consists mostly of bits and pieces from the GNU C
21    Library version 2.2.4. The pieces come from stdlib/drand48-iter.c,
22    stdlib/stdlib.h, stdlib/nrand48_r.c, and stdlib/lrand48.c. */
23 
24 typedef unsigned long long uint64_t;
25 typedef unsigned int uint32_t;
26 
27 /* Data structure for communication with thread safe versions.  This
28    type is to be regarded as opaque.  It's only exported because users
29    have to allocate objects of this type.  */
30 struct drand48_data
31   {
32     unsigned short int __x[3];  /* Current state.  */
33     unsigned short int __old_x[3]; /* Old state.  */
34     unsigned short int __c; /* Additive const. in congruential formula.  */
35     unsigned short int __init;  /* Flag for initializing.  */
36     unsigned long long int __a; /* Factor in congruential formula.  */
37   };
38 
39 /* Global state for non-reentrant functions.  */
40 struct drand48_data __libc_drand48_data;
41 
42 int
__drand48_iterate(xsubi,buffer)43 __drand48_iterate (xsubi, buffer)
44      unsigned short int xsubi[3];
45      struct drand48_data *buffer;
46 {
47   uint64_t X;
48   uint64_t result;
49 
50   /* Initialize buffer, if not yet done.  */
51   if (!buffer->__init)
52     {
53       buffer->__a = 0x5deece66dull;
54       buffer->__c = 0xb;
55       buffer->__init = 1;
56     }
57 
58   /* Do the real work.  We choose a data type which contains at least
59      48 bits.  Because we compute the modulus it does not care how
60      many bits really are computed.  */
61 
62   X = (uint64_t) xsubi[2] << 32 | (uint32_t) xsubi[1] << 16 | xsubi[0];
63 
64   result = X * buffer->__a + buffer->__c;
65 
66   xsubi[0] = result & 0xffff;
67   xsubi[1] = (result >> 16) & 0xffff;
68   xsubi[2] = (result >> 32) & 0xffff;
69 
70   return 0;
71 }
72 
73 int
__nrand48_r(xsubi,buffer,result)74 __nrand48_r (xsubi, buffer, result)
75      unsigned short int xsubi[3];
76      struct drand48_data *buffer;
77      long int *result;
78 {
79   /* Compute next state.  */
80   if (__drand48_iterate (xsubi, buffer) < 0)
81     return -1;
82 
83   /* Store the result.  */
84   if (sizeof (unsigned short int) == 2)
85     *result = xsubi[2] << 15 | xsubi[1] >> 1;
86   else
87     *result = xsubi[2] >> 1;
88 
89   return 0;
90 }
91 
92 long int
lrand48()93 lrand48 ()
94 {
95   long int result;
96 
97   (void) __nrand48_r (__libc_drand48_data.__x, &__libc_drand48_data, &result);
98 
99   return result;
100 }
101