| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| /* |
| * $Id$ |
| * |
| * 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.2 2007/04/07 08:10:40 cmcdevitt |
| * Fixes for dbgen with large scale factors |
| * |
| * 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; |
| |
| 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; |
| } |