]> granicus.if.org Git - postgresql/blob - src/port/rand.c
8.4 pgindent run, with new combined Linux/FreeBSD/MinGW typedef list
[postgresql] / src / port / rand.c
1 /*
2  * $PostgreSQL: pgsql/src/port/rand.c,v 1.6 2009/06/11 14:49:15 momjian Exp $
3  *
4  *-------------------------------------------------------------------------
5  *
6  * rand.c
7  *        Missing rand implementations for Win32
8  *
9  *-------------------------------------------------------------------------
10  */
11 #include "c.h"
12
13 /*
14  * Copyright (c) 1993 Martin Birgmeier
15  * All rights reserved.
16  *
17  * You may redistribute unmodified or modified versions of this source
18  * code provided that the above copyright notice and this and the
19  * following conditions are retained.
20  *
21  * This software is provided ``as is'', and comes with no warranties
22  * of any kind. I shall in no event be liable for anything that happens
23  * to anyone/anything when using this software.
24  */
25 #define RAND48_SEED_0   (0x330e)
26 #define RAND48_SEED_1   (0xabcd)
27 #define RAND48_SEED_2   (0x1234)
28 #define RAND48_MULT_0   (0xe66d)
29 #define RAND48_MULT_1   (0xdeec)
30 #define RAND48_MULT_2   (0x0005)
31 #define RAND48_ADD              (0x000b)
32
33 unsigned short _rand48_seed[3] = {
34         RAND48_SEED_0,
35         RAND48_SEED_1,
36         RAND48_SEED_2
37 };
38 unsigned short _rand48_mult[3] = {
39         RAND48_MULT_0,
40         RAND48_MULT_1,
41         RAND48_MULT_2
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] +
52                 (unsigned long) _rand48_add;
53         temp[0] = (unsigned short) accu;        /* lower 16 bits */
54         accu >>= sizeof(unsigned short) * 8;
55         accu += (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 }