CUBRID Engine  latest
rand.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 1993 Martin Birgmeier
3  * All rights reserved.
4  *
5  * You may redistribute unmodified or modified versions of this source
6  * code provided that the above copyright notice and this and the
7  * following conditions are retained.
8  *
9  * This software is provided ``as is'', and comes with no warranties
10  * of any kind. I shall in no event be liable for anything that happens
11  * to anyone/anything when using this software.
12  */
13 
14 /*
15  * rand.c - rand48 implementations for Windows
16  */
17 
18 #if defined (WINDOWS)
19 #include "porting.h"
20 #define LRAND48_MAX (2147483648)
21 
22 #define RAND48_SEED_0 (0x330e)
23 #define RAND48_SEED_1 (0xabcd)
24 #define RAND48_SEED_2 (0x1234)
25 #define RAND48_MULT_0 (0xe66d)
26 #define RAND48_MULT_1 (0xdeec)
27 #define RAND48_MULT_2 (0x0005)
28 #define RAND48_ADD (0x000b)
29 
30 
31 unsigned short _rand48_seed[3] = {
32  RAND48_SEED_0,
33  RAND48_SEED_1,
34  RAND48_SEED_2
35 };
36 
37 unsigned short _rand48_mult[3] = {
38  RAND48_MULT_0,
39  RAND48_MULT_1,
40  RAND48_MULT_2
41 };
42 
43 unsigned short _rand48_add = RAND48_ADD;
44 
45 static void
46 _dorand48 (unsigned short xseed[3])
47 {
48  unsigned long accu;
49  unsigned short temp[2];
50 
51  accu = (unsigned long) _rand48_mult[0] * (unsigned long) xseed[0] + (unsigned long) _rand48_add;
52  temp[0] = (unsigned short) accu; /* lower 16 bits */
53  accu >>= sizeof (unsigned short) * 8;
54  accu +=
55  (unsigned long) _rand48_mult[0] * (unsigned long) xseed[1] +
56  (unsigned long) _rand48_mult[1] * (unsigned long) xseed[0];
57  temp[1] = (unsigned short) accu; /* middle 16 bits */
58  accu >>= sizeof (unsigned short) * 8;
59  accu += _rand48_mult[0] * xseed[2] + _rand48_mult[1] * xseed[1] + _rand48_mult[2] * xseed[0];
60  xseed[0] = temp[0];
61  xseed[1] = temp[1];
62  xseed[2] = (unsigned short) accu;
63 }
64 
65 long
66 lrand48 (void)
67 {
68  _dorand48 (_rand48_seed);
69  return ((long) _rand48_seed[2] << 15) + ((long) _rand48_seed[1] >> 1);
70 }
71 
72 void
73 srand48 (long seed)
74 {
75  _rand48_seed[0] = RAND48_SEED_0;
76  _rand48_seed[1] = (unsigned short) seed;
77  _rand48_seed[2] = (unsigned short) (seed >> 16);
78  _rand48_mult[0] = RAND48_MULT_0;
79  _rand48_mult[1] = RAND48_MULT_1;
80  _rand48_mult[2] = RAND48_MULT_2;
81  _rand48_add = RAND48_ADD;
82 }
83 
84 double
85 drand48 (void)
86 {
87  /* lrand48 returns a number between 0 and 2^31-1. So, we divide it by 2^31 to generate floating-point value
88  * uniformly distributed between [0.0, 1.0). */
89  return (double) ((double) lrand48 () / (double) LRAND48_MAX);
90 }
91 
92 int
93 srand48_r (long int seed, struct drand48_data *buffer)
94 {
95  buffer->_rand48_seed[0] = RAND48_SEED_0;
96  buffer->_rand48_seed[1] = (unsigned short) seed;
97  buffer->_rand48_seed[2] = (unsigned short) (seed >> 16);
98  return 0;
99 }
100 
101 int
102 lrand48_r (struct drand48_data *buffer, long int *result)
103 {
104  _dorand48 (buffer->_rand48_seed);
105  if (result)
106  {
107  *result = ((long) buffer->_rand48_seed[2] << 15) + ((long) buffer->_rand48_seed[1] >> 1);
108  }
109  return 0;
110 }
111 
112 int
113 drand48_r (struct drand48_data *buffer, double *result)
114 {
115  long int r;
116  lrand48_r (buffer, &r);
117  if (result)
118  {
119  *result = (double) ((double) r / (double) LRAND48_MAX);
120  }
121  return 0;
122 }
123 
124 int
125 rand_r (unsigned int *seedp)
126 {
127  unsigned int ret;
128  if (rand_s (&ret) == 0)
129  {
130  return ret;
131  }
132  return 0;
133 }
134 #endif /* WINDOWS */