-
Notifications
You must be signed in to change notification settings - Fork 132
/
rng64.c
140 lines (126 loc) · 3.7 KB
/
rng64.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
/*
* $Id: rng64.c,v 1.7 2008/03/21 17:38:39 jms Exp $
*
* This software contains proprietary and confidential information of Gradient
* Systems Inc. By accepting transfer of this copy, Recipient agrees
* to retain this software in confidence, to prevent disclosure to others, and
* to make no use of this software other than that for which it was delivered.
* This is an unpublished copyright work Gradient Systems, Inc. Execpt as
* permitted by federal law, 17 USC 117, copying is strictly prohibited.
*
* Gradient Systems Inc. CONFIDENTIAL - (Gradient Systems Inc. Confidential
* when combined with the aggregated modules for this product)
* OBJECT CODE ONLY SOURCE MATERIALS
* (C) COPYRIGHT Gradient Systems Inc. 2003
*
* All Rights Reserved
* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF GRADIENT SYSTEMS, INC.
* The copyright notice above does not evidence any
* actual or intended publication of such source code.
*
* Revision History
* ===================
* $Log: rng64.c,v $
* Revision 1.7 2008/03/21 17:38:39 jms
* changes for 2.6.3
*
* Revision 1.6 2006/04/26 23:20:05 jms
* Data type clenaup for qgen
*
* Revision 1.5 2006/03/08 21:25:27 jms
* change to RNG64 to address overflow/underflow issues
*
* Revision 1.4 2005/10/25 17:26:38 jms
* check in integration between microsoft changes and baseline code
*
* Revision 1.3 2005/03/04 19:48:39 jms
* Changes from Doug Johnson to address very large scale factors
*
* Revision 1.2 2005/01/03 20:08:59 jms
* change line terminations
*
* Revision 1.1.1.1 2004/11/24 23:31:47 jms
* re-establish external server
*
* Revision 1.2 2004/02/18 16:45:30 jms
* remove C++ style comments for AIX compiler
*
* Revision 1.1.1.1 2003/08/08 21:57:34 jms
* recreation after CVS crash
*
* Revision 1.1 2003/08/08 21:57:34 jms
* first integration of rng64 for o_custkey and l_partkey
*
*/
#include "config.h"
#include "dss.h"
#include <stdio.h>
#include <stdlib.h>
#include "rng64.h"
extern double dM;
extern seed_t Seed[];
void
dss_random64(DSS_HUGE *tgt, DSS_HUGE nLow, DSS_HUGE nHigh, long nStream)
{
DSS_HUGE nTemp;
if (nStream < 0 || nStream > MAX_STREAM)
nStream = 0;
if (nLow > nHigh)
{
nTemp = nLow;
nLow = nHigh;
nHigh = nTemp;
}
Seed[nStream].value = NextRand64(Seed[nStream].value);
nTemp = Seed[nStream].value;
if (nTemp < 0)
nTemp = -nTemp;
nTemp %= (nHigh - nLow + 1);
*tgt = nLow + nTemp;
Seed[nStream].usage += 1;
#ifdef RNG_TEST
Seed[nStream].nCalls += 1;
#endif
return;
}
DSS_HUGE
NextRand64(DSS_HUGE nSeed){
DSS_HUGE a = (unsigned DSS_HUGE) RNG_A;
DSS_HUGE c = (unsigned DSS_HUGE) RNG_C;
nSeed = (nSeed * a + c); /* implicitely truncated to 64bits */
return (nSeed);
}
DSS_HUGE AdvanceRand64( DSS_HUGE nSeed,
DSS_HUGE nCount) {
unsigned DSS_HUGE a = RNG_A ;
unsigned DSS_HUGE c = RNG_C ;
int nBit;
unsigned DSS_HUGE Apow=a, Dsum=c;
/* if nothing to do, do nothing ! */
if( nCount == 0 ) return nSeed;
/* Recursively compute X(n) = A * X(n-1) + C */
/* */
/* explicitely: */
/* X(n) = A^n * X(0) + { A^(n-1) + A^(n-2) + ... A + 1 } * C */
/* */
/* we write this as: */
/* X(n) = Apow(n) * X(0) + Dsum(n) * C */
/* */
/* we use the following relations: */
/* Apow(n) = A^(n%2)*Apow(n/2)*Apow(n/2) */
/* Dsum(n) = (n%2)*Apow(n/2)*Apow(n/2) + (Apow(n/2) + 1) * Dsum(n/2) */
/* */
/* first get the highest non-zero bit */
for( nBit = 0; (nCount >> nBit) != RNG_C ; nBit ++){}
/* go 1 bit at the time */
while( --nBit >= 0 ) {
Dsum *= (Apow + 1);
Apow = Apow * Apow;
if( ((nCount >> nBit) % 2) == 1 ) { /* odd value */
Dsum += Apow;
Apow *= a;
}
}
nSeed = nSeed * Apow + Dsum * c;
return nSeed;
}