OSDN Git Service

Update a number of broken links in comments.
[pg-rex/syncrep.git] / src / port / erand48.c
1 /*-------------------------------------------------------------------------
2  *
3  * erand48.c
4  *
5  * This file supplies versions of erand48(), lrand48(), and srand48()
6  * for machines that lack them.  (These are all the members of the drand48
7  * family that Postgres currently requires.  We name the file after erand48
8  * because that is the one that configure tests for.)
9  *
10  *
11  * Copyright (c) 1993 Martin Birgmeier
12  * All rights reserved.
13  *
14  * You may redistribute unmodified or modified versions of this source
15  * code provided that the above copyright notice and this and the
16  * following conditions are retained.
17  *
18  * This software is provided ``as is'', and comes with no warranties
19  * of any kind. I shall in no event be liable for anything that happens
20  * to anyone/anything when using this software.
21  *
22  * IDENTIFICATION
23  *        $PostgreSQL: pgsql/src/port/erand48.c,v 1.1 2009/07/16 17:43:52 tgl Exp $
24  *
25  *-------------------------------------------------------------------------
26  */
27
28 #include "c.h"
29
30 #include <math.h>
31
32 #define RAND48_SEED_0   (0x330e)
33 #define RAND48_SEED_1   (0xabcd)
34 #define RAND48_SEED_2   (0x1234)
35 #define RAND48_MULT_0   (0xe66d)
36 #define RAND48_MULT_1   (0xdeec)
37 #define RAND48_MULT_2   (0x0005)
38 #define RAND48_ADD              (0x000b)
39
40 static unsigned short _rand48_seed[3] = {
41         RAND48_SEED_0,
42         RAND48_SEED_1,
43         RAND48_SEED_2
44 };
45 static unsigned short _rand48_mult[3] = {
46         RAND48_MULT_0,
47         RAND48_MULT_1,
48         RAND48_MULT_2
49 };
50 static unsigned short _rand48_add = RAND48_ADD;
51
52
53 static void
54 _dorand48(unsigned short xseed[3])
55 {
56         unsigned long accu;
57         unsigned short temp[2];
58
59         accu = (unsigned long) _rand48_mult[0] * (unsigned long) xseed[0] +
60                 (unsigned long) _rand48_add;
61         temp[0] = (unsigned short) accu;        /* lower 16 bits */
62         accu >>= sizeof(unsigned short) * 8;
63         accu += (unsigned long) _rand48_mult[0] * (unsigned long) xseed[1] +
64                 (unsigned long) _rand48_mult[1] * (unsigned long) xseed[0];
65         temp[1] = (unsigned short) accu;        /* middle 16 bits */
66         accu >>= sizeof(unsigned short) * 8;
67         accu += _rand48_mult[0] * xseed[2] + _rand48_mult[1] * xseed[1] + _rand48_mult[2] * xseed[0];
68         xseed[0] = temp[0];
69         xseed[1] = temp[1];
70         xseed[2] = (unsigned short) accu;
71 }
72
73
74 double
75 erand48(unsigned short xseed[3])
76 {
77         _dorand48(xseed);
78         return ldexp((double) xseed[0], -48) +
79                 ldexp((double) xseed[1], -32) +
80                 ldexp((double) xseed[2], -16);
81 }
82
83 long
84 lrand48(void)
85 {
86         _dorand48(_rand48_seed);
87         return ((long) _rand48_seed[2] << 15) + ((long) _rand48_seed[1] >> 1);
88 }
89
90 void
91 srand48(long seed)
92 {
93         _rand48_seed[0] = RAND48_SEED_0;
94         _rand48_seed[1] = (unsigned short) seed;
95         _rand48_seed[2] = (unsigned short) (seed > 16);
96         _rand48_mult[0] = RAND48_MULT_0;
97         _rand48_mult[1] = RAND48_MULT_1;
98         _rand48_mult[2] = RAND48_MULT_2;
99         _rand48_add = RAND48_ADD;
100 }