| 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 "rng64.h" | 
|---|
| 56 |  | 
|---|
| 57 | #include <stdio.h> | 
|---|
| 58 | #include <stdlib.h> | 
|---|
| 59 | extern double dM; | 
|---|
| 60 |  | 
|---|
| 61 | extern seed_t Seed[]; | 
|---|
| 62 |  | 
|---|
| 63 | void dss_random64(DSS_HUGE *tgt, DSS_HUGE nLow, DSS_HUGE nHigh, long nStream) { | 
|---|
| 64 | DSS_HUGE nTemp; | 
|---|
| 65 |  | 
|---|
| 66 | if (nStream < 0 || nStream > MAX_STREAM) | 
|---|
| 67 | nStream = 0; | 
|---|
| 68 |  | 
|---|
| 69 | if (nLow > nHigh) { | 
|---|
| 70 | nTemp = nLow; | 
|---|
| 71 | nLow = nHigh; | 
|---|
| 72 | nHigh = nTemp; | 
|---|
| 73 | } | 
|---|
| 74 |  | 
|---|
| 75 | Seed[nStream].value = NextRand64(Seed[nStream].value); | 
|---|
| 76 | nTemp = Seed[nStream].value; | 
|---|
| 77 | if (nTemp < 0) | 
|---|
| 78 | nTemp = -nTemp; | 
|---|
| 79 | nTemp %= (nHigh - nLow + 1); | 
|---|
| 80 | *tgt = nLow + nTemp; | 
|---|
| 81 | Seed[nStream].usage += 1; | 
|---|
| 82 | #ifdef RNG_TEST | 
|---|
| 83 | Seed[nStream].nCalls += 1; | 
|---|
| 84 | #endif | 
|---|
| 85 |  | 
|---|
| 86 | return; | 
|---|
| 87 | } | 
|---|
| 88 |  | 
|---|
| 89 | DSS_HUGE | 
|---|
| 90 | NextRand64(DSS_HUGE nSeed) { | 
|---|
| 91 |  | 
|---|
| 92 | DSS_HUGE a = (unsigned DSS_HUGE)RNG_A; | 
|---|
| 93 | DSS_HUGE c = (unsigned DSS_HUGE)RNG_C; | 
|---|
| 94 | nSeed = (nSeed * a + c); /* implicitely truncated to 64bits */ | 
|---|
| 95 |  | 
|---|
| 96 | return (nSeed); | 
|---|
| 97 | } | 
|---|
| 98 |  | 
|---|
| 99 | DSS_HUGE AdvanceRand64(DSS_HUGE nSeed, DSS_HUGE nCount) { | 
|---|
| 100 | unsigned DSS_HUGE a = RNG_A; | 
|---|
| 101 | unsigned DSS_HUGE c = RNG_C; | 
|---|
| 102 | int nBit; | 
|---|
| 103 | unsigned DSS_HUGE Apow = a, Dsum = c; | 
|---|
| 104 |  | 
|---|
| 105 | /* if nothing to do, do nothing ! */ | 
|---|
| 106 | if (nCount == 0) | 
|---|
| 107 | return nSeed; | 
|---|
| 108 |  | 
|---|
| 109 | /* Recursively compute X(n) = A * X(n-1) + C */ | 
|---|
| 110 | /* */ | 
|---|
| 111 | /* explicitely: */ | 
|---|
| 112 | /* X(n) = A^n * X(0) + { A^(n-1) + A^(n-2) + ... A + 1 } * C */ | 
|---|
| 113 | /* */ | 
|---|
| 114 | /* we write this as: */ | 
|---|
| 115 | /* X(n) = Apow(n) * X(0) + Dsum(n) * C */ | 
|---|
| 116 | /* */ | 
|---|
| 117 | /* we use the following relations: */ | 
|---|
| 118 | /* Apow(n) = A^(n%2)*Apow(n/2)*Apow(n/2) */ | 
|---|
| 119 | /* Dsum(n) =   (n%2)*Apow(n/2)*Apow(n/2) + (Apow(n/2) + 1) * Dsum(n/2) */ | 
|---|
| 120 | /* */ | 
|---|
| 121 |  | 
|---|
| 122 | /* first get the highest non-zero bit */ | 
|---|
| 123 | for (nBit = 0; (nCount >> nBit) != RNG_C; nBit++) { | 
|---|
| 124 | } | 
|---|
| 125 |  | 
|---|
| 126 | /* go 1 bit at the time */ | 
|---|
| 127 | while (--nBit >= 0) { | 
|---|
| 128 | Dsum *= (Apow + 1); | 
|---|
| 129 | Apow = Apow * Apow; | 
|---|
| 130 | if (((nCount >> nBit) % 2) == 1) { /* odd value */ | 
|---|
| 131 | Dsum += Apow; | 
|---|
| 132 | Apow *= a; | 
|---|
| 133 | } | 
|---|
| 134 | } | 
|---|
| 135 | nSeed = nSeed * Apow + Dsum * c; | 
|---|
| 136 | return nSeed; | 
|---|
| 137 | } | 
|---|
| 138 |  | 
|---|