1/*
2* $Id: rng64.c,v 1.7 2008/03/21 17:38:39 jms Exp $
3*
4* This software contains proprietary and confidential information of Gradient
5* Systems Inc. By accepting transfer of this copy, Recipient agrees
6* to retain this software in confidence, to prevent disclosure to others, and
7* to make no use of this software other than that for which it was delivered.
8* This is an unpublished copyright work Gradient Systems, Inc. Execpt as
9* permitted by federal law, 17 USC 117, copying is strictly prohibited.
10*
11* Gradient Systems Inc. CONFIDENTIAL - (Gradient Systems Inc. Confidential
12* when combined with the aggregated modules for this product)
13* OBJECT CODE ONLY SOURCE MATERIALS
14* (C) COPYRIGHT Gradient Systems Inc. 2003
15*
16* All Rights Reserved
17* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF GRADIENT SYSTEMS, INC.
18* The copyright notice above does not evidence any
19* actual or intended publication of such source code.
20*
21* Revision History
22* ===================
23* $Log: rng64.c,v $
24* Revision 1.7 2008/03/21 17:38:39 jms
25* changes for 2.6.3
26*
27* Revision 1.6 2006/04/26 23:20:05 jms
28* Data type clenaup for qgen
29*
30* Revision 1.5 2006/03/08 21:25:27 jms
31* change to RNG64 to address overflow/underflow issues
32*
33* Revision 1.4 2005/10/25 17:26:38 jms
34* check in integration between microsoft changes and baseline code
35*
36* Revision 1.3 2005/03/04 19:48:39 jms
37* Changes from Doug Johnson to address very large scale factors
38*
39* Revision 1.2 2005/01/03 20:08:59 jms
40* change line terminations
41*
42* Revision 1.1.1.1 2004/11/24 23:31:47 jms
43* re-establish external server
44*
45* Revision 1.2 2004/02/18 16:45:30 jms
46* remove C++ style comments for AIX compiler
47*
48* Revision 1.1.1.1 2003/08/08 21:57:34 jms
49* recreation after CVS crash
50*
51* Revision 1.1 2003/08/08 21:57:34 jms
52* first integration of rng64 for o_custkey and l_partkey
53*
54*/
55#include "config.h"
56#include "dss.h"
57#include <stdio.h>
58#include <stdlib.h>
59#include "rng64.h"
60extern double dM;
61
62extern seed_t Seed[];
63
64void
65dss_random64(DSS_HUGE *tgt, DSS_HUGE nLow, DSS_HUGE nHigh, long nStream)
66{
67 DSS_HUGE nTemp;
68
69 if (nStream < 0 || nStream > MAX_STREAM)
70 nStream = 0;
71
72 if (nLow > nHigh)
73 {
74 nTemp = nLow;
75 nLow = nHigh;
76 nHigh = nTemp;
77 }
78
79 Seed[nStream].value = NextRand64(Seed[nStream].value);
80 nTemp = Seed[nStream].value;
81 if (nTemp < 0)
82 nTemp = -nTemp;
83 nTemp %= (nHigh - nLow + 1);
84 *tgt = nLow + nTemp;
85 Seed[nStream].usage += 1;
86#ifdef RNG_TEST
87 Seed[nStream].nCalls += 1;
88#endif
89
90 return;
91}
92
93DSS_HUGE
94NextRand64(DSS_HUGE nSeed){
95
96 DSS_HUGE a = (unsigned DSS_HUGE) RNG_A;
97 DSS_HUGE c = (unsigned DSS_HUGE) RNG_C;
98 nSeed = (nSeed * a + c); /* implicitely truncated to 64bits */
99
100 return (nSeed);
101}
102
103DSS_HUGE AdvanceRand64( DSS_HUGE nSeed,
104 DSS_HUGE nCount) {
105 unsigned DSS_HUGE a = RNG_A ;
106 unsigned DSS_HUGE c = RNG_C ;
107 int nBit;
108 unsigned DSS_HUGE Apow=a, Dsum=c;
109
110 /* if nothing to do, do nothing ! */
111 if( nCount == 0 ) return nSeed;
112
113 /* Recursively compute X(n) = A * X(n-1) + C */
114 /* */
115 /* explicitely: */
116 /* X(n) = A^n * X(0) + { A^(n-1) + A^(n-2) + ... A + 1 } * C */
117 /* */
118 /* we write this as: */
119 /* X(n) = Apow(n) * X(0) + Dsum(n) * C */
120 /* */
121 /* we use the following relations: */
122 /* Apow(n) = A^(n%2)*Apow(n/2)*Apow(n/2) */
123 /* Dsum(n) = (n%2)*Apow(n/2)*Apow(n/2) + (Apow(n/2) + 1) * Dsum(n/2) */
124 /* */
125
126 /* first get the highest non-zero bit */
127 for( nBit = 0; (nCount >> nBit) != RNG_C ; nBit ++){}
128
129 /* go 1 bit at the time */
130 while( --nBit >= 0 ) {
131 Dsum *= (Apow + 1);
132 Apow = Apow * Apow;
133 if( ((nCount >> nBit) % 2) == 1 ) { /* odd value */
134 Dsum += Apow;
135 Apow *= a;
136 }
137 }
138 nSeed = nSeed * Apow + Dsum * c;
139 return nSeed;
140}
141