forked from kjc0066/hhh
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrand48.c
146 lines (130 loc) · 3.63 KB
/
rand48.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/*
* Copyright (c) 1993 Martin Birgmeier
* All rights reserved.
*
* You may redistribute unmodified or modified versions of this source
* code provided that the above copyright notice and this and the
* following conditions are retained.
*
* This software is provided ``as is'', and comes with no warranties
* of any kind. I shall in no event be liable for anything that happens
* to anyone/anything when using this software.
*/
#include <math.h>
#include <stdlib.h>
#define RAND48_SEED_0 (0x330e)
#define RAND48_SEED_1 (0xabcd)
#define RAND48_SEED_2 (0x1234)
#define RAND48_MULT_0 (0xe66d)
#define RAND48_MULT_1 (0xdeec)
#define RAND48_MULT_2 (0x0005)
#define RAND48_ADD (0x000b)
/* Internal function to compute next state of the generator. */
static void _dorand48(unsigned short[3]);
/* Unfortunately, 3 __globals, which the exported functions must access */
unsigned short __rand48_Seed[3] = {
RAND48_SEED_0,
RAND48_SEED_1,
RAND48_SEED_2
};
unsigned short __rand48_Mult[3] = {
RAND48_MULT_0,
RAND48_MULT_1,
RAND48_MULT_2
};
unsigned short __rand48_Add = RAND48_ADD;
/* Internal function to compute next state of the generator. */
static void
_dorand48(unsigned short xseed[3])
{
unsigned long accu;
unsigned short temp[2];
accu = (unsigned long) __rand48_Mult[0] * (unsigned long) xseed[0] +
(unsigned long) __rand48_Add;
temp[0] = (unsigned short) accu; /* lower 16 bits */
accu >>= sizeof(unsigned short) * 8;
accu += (unsigned long) __rand48_Mult[0] * (unsigned long) xseed[1] +
(unsigned long) __rand48_Mult[1] * (unsigned long) xseed[0];
temp[1] = (unsigned short) accu; /* middle 16 bits */
accu >>= sizeof(unsigned short) * 8;
accu += __rand48_Mult[0] * xseed[2] + __rand48_Mult[1] * xseed[1] +
__rand48_Mult[2] * xseed[0];
xseed[0] = temp[0];
xseed[1] = temp[1];
xseed[2] = (unsigned short) accu;
}
extern void
srand48(long seed)
{
__rand48_Seed[0] = RAND48_SEED_0;
__rand48_Seed[1] = (unsigned short) seed;
__rand48_Seed[2] = (unsigned short) (seed >> 16);
__rand48_Mult[0] = RAND48_MULT_0;
__rand48_Mult[1] = RAND48_MULT_1;
__rand48_Mult[2] = RAND48_MULT_2;
__rand48_Add = RAND48_ADD;
}
extern unsigned short *
seed48(unsigned short xseed[3])
{
static unsigned short sseed[3];
sseed[0] = __rand48_Seed[0];
sseed[1] = __rand48_Seed[1];
sseed[2] = __rand48_Seed[2];
__rand48_Seed[0] = xseed[0];
__rand48_Seed[1] = xseed[1];
__rand48_Seed[2] = xseed[2];
__rand48_Mult[0] = RAND48_MULT_0;
__rand48_Mult[1] = RAND48_MULT_1;
__rand48_Mult[2] = RAND48_MULT_2;
__rand48_Add = RAND48_ADD;
return sseed;
}
extern long
nrand48(unsigned short xseed[3])
{
_dorand48(xseed);
return ((long) xseed[2] << 15) + ((long) xseed[1] >> 1);
}
extern long
mrand48(void)
{
_dorand48(__rand48_Seed);
return ((long) __rand48_Seed[2] << 16) + (long) __rand48_Seed[1];
}
extern long
lrand48(void)
{
_dorand48(__rand48_Seed);
return ((long) __rand48_Seed[2] << 15) + ((long) __rand48_Seed[1] >> 1);
}
extern void
lcong48(unsigned short p[7])
{
__rand48_Seed[0] = p[0];
__rand48_Seed[1] = p[1];
__rand48_Seed[2] = p[2];
__rand48_Mult[0] = p[3];
__rand48_Mult[1] = p[4];
__rand48_Mult[2] = p[5];
__rand48_Add = p[6];
}
extern long
jrand48(unsigned short xseed[3])
{
_dorand48(xseed);
return ((long) xseed[2] << 16) + (long) xseed[1];
}
extern double
erand48(unsigned short xseed[3])
{
_dorand48(xseed);
return ldexp((double) xseed[0], -48) +
ldexp((double) xseed[1], -32) +
ldexp((double) xseed[2], -16);
}
extern double
drand48(void)
{
return erand48(__rand48_Seed);
}