1
/**********************************************************************
2
Copyright (C) 1998-2001 by OpenEye Scientific Software, Inc.
4
This program is free software; you can redistribute it and/or modify
5
it under the terms of the GNU General Public License as published by
6
the Free Software Foundation version 2 of the License.
8
This program is distributed in the hope that it will be useful,
9
but WITHOUT ANY WARRANTY; without even the implied warranty of
10
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
GNU General Public License for more details.
12
***********************************************************************/
14
/* derived from sample.c
15
* Pseudo-Random Number Generator Generator
16
* Roger Sayle, Metaphorics LLC
17
* Version 1.2, September 1998
32
#define IsEven(x) (((x)&1)==0)
33
#define IsOdd(x) (((x)&1)!=0)
35
#define BothEven(x,y) IsEven((x)|(y))
36
#define IsPrime(x) (!IsEven((x))&&IsOddPrime((x)))
38
#define HiPart(x) (x>>16)
39
#define LoPart(x) ((x)&0xffff)
41
/* The maximum number of unique prime factors of a 32 bit number */
42
/* 2*3*5*7*11*13*17*19*23*29 = 6469693230 > 2^32 = 4294967296 */
47
static int primes[MAXPRIMES] = {
48
1, 2, 3, 5, 7, 11, 13, 17, 19, 23,
49
29, 31, 37, 41, 43, 47, 53, 59, 61, 67,
50
71, 73, 79, 83, 89, 97, 101, 103, 107, 109,
51
113, 127, 131, 137, 139, 149, 151, 157, 163, 167,
52
173, 179, 181, 191, 193, 197, 199, 211, 223, 227,
53
229, 233, 239, 241, 251, 257, 263, 269, 271, 277,
54
281, 283, 293, 307, 311, 313, 317, 331, 337, 347,
55
349, 353, 359, 367, 373, 379, 383, 389, 397, 401,
56
409, 419, 421, 431, 433, 439, 443, 449, 457, 461,
57
463, 467, 479, 487, 491, 499, 503, 509, 521, 523,
58
541, 547, 557, 563, 569, 571, 577, 587, 593, 599,
59
601, 607, 613, 617, 619, 631, 641, 643, 647, 653,
60
659, 661, 673, 677, 683, 691, 701, 709, 719, 727,
61
733, 739, 743, 751, 757, 761, 769, 773, 787, 797,
62
809, 811, 821, 823, 827, 829, 839, 853, 857, 859,
63
863, 877, 881, 883, 887, 907, 911, 919, 929, 937,
64
941, 947, 953, 967, 971, 977, 983, 991, 997, 1009,
65
1013, 1019, 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063,
66
1069, 1087, 1091, 1093, 1097, 1103, 1109, 1117, 1123, 1129,
67
1151, 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213, 1217,
68
1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283, 1289,
69
1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367,
70
1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447,
71
1451, 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499,
72
1511, 1523, 1531, 1543, 1549, 1553, 1559, 1567, 1571, 1579,
73
1583, 1597, 1601, 1607, 1609, 1613
76
static unsigned int isqrt( unsigned int val )
78
register unsigned int temp;
79
register unsigned int rem;
80
register int i,result;
83
while( !(val&((unsigned int)3<<30)) && i )
95
{ rem = (rem<<2) | (val>>30);
110
static int IsOddPrime( unsigned int x )
112
register unsigned int root;
113
register unsigned int i;
116
for( i=2; i<MAXPRIMES-1; i++ )
117
{ if( (x%primes[i]) == 0 )
119
if( (unsigned int) primes[i] >= root )
123
for( i=primes[MAXPRIMES-1]; i<=root; i+=2 )
129
static int RelativelyPrime( unsigned int x, unsigned int y )
137
} while( IsEven(x) );
147
} while( IsEven(x) );
152
} while( IsEven(y) );
158
void DoubleAdd( DoubleType *x, unsigned int y )
165
void DoubleMultiply( unsigned int x, unsigned int y, DoubleType *z )
167
register unsigned int x0, x1, x2, x3;
168
register unsigned int hx, lx;
169
register unsigned int hy, ly;
186
z->hi = HiPart(x1) + x3;
187
z->lo = (LoPart(x1)<<16) + LoPart(x0);
190
static int LeadingZeros( unsigned int x )
192
static int table[256] = {
193
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
194
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
195
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
196
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
197
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
198
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
199
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
200
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
205
{ return 8-table[x>>24];
206
} else return 16-table[x>>16];
207
} else if( x >= (1<<8) )
208
{ return 24-table[x>>8];
209
} else return 32-table[x];
212
unsigned int DoubleModulus( DoubleType *n, unsigned int d )
214
register unsigned int d1, d0;
215
register unsigned int r1, r0;
216
register unsigned int m,s;
221
n->hi = (n->hi<<s) | (n->lo>>(32-s));
228
m = ((unsigned int)(n->hi/d1)) * d0;
229
r1 = ((n->hi%d1)<<16) + HiPart(n->lo);
232
if( (r1>=d) && (r1<m) )
237
m = ((unsigned int)(r1/d1)) * d0;
238
r0 = ((r1%d1)<<16) + LoPart(n->lo);
241
if( (r0>=d) && (r0<m) )
249
static int DeterminePotency( unsigned int m, unsigned int a )
252
register unsigned int k;
253
register unsigned int b;
258
while( (k!=0) && (s<100) )
259
{ DoubleMultiply(k,b,&d);
260
k = DoubleModulus(&d,m);
266
static int DetermineFactors( unsigned int x, unsigned int *factors )
268
register unsigned int *ptr;
269
register unsigned int half;
270
register unsigned int i;
274
for( i=1; i<MAXPRIMES; i++ )
275
{ if( (x%primes[i]) == 0 )
277
if( (unsigned int)(primes[i]) >= half )
281
for( i=primes[MAXPRIMES-1]+2; i<=half; i+=2 )
282
if( IsOddPrime(i) && ((x%i)==0) )
287
static unsigned int DetermineIncrement( unsigned int m )
289
register unsigned int hi,lo;
290
register unsigned int half;
291
register unsigned int i;
293
/* 1/2 + sqrt(3)/6 */
294
hi = (int)floor(0.7886751345948*m+0.5);
295
if( RelativelyPrime(m,hi) )
298
/* 1/2 - sqrt(3)/6 */
299
lo = (int)floor(0.2113248654052*m+0.5);
300
if( RelativelyPrime(m,lo) )
304
for( i=1; i<half; i++ )
305
{ if( RelativelyPrime(m,hi+i) )
307
if( RelativelyPrime(m,hi-i) )
309
if( RelativelyPrime(m,lo+i) )
311
if( RelativelyPrime(m,lo-i) )
317
int DetermineSequence( unsigned int m, unsigned int *pm,
321
auto unsigned int fact[MAXFACT];
322
register unsigned int a=0, c;
323
register unsigned int b;
324
register int pot,best;
332
count = DetermineFactors(m,fact);
333
if( (m&3) == 0 ) fact[0] = 4;
336
printf("factors(%d):",m);
342
printf("%u",fact[0]);
343
for( i=1; i<count; i++ )
344
printf(",%u",fact[i]);
347
for( b=m-2; b>0; b-- )
349
for( i=0; i<count; i++ )
356
{ pot = DeterminePotency(m,b+1);
366
printf(" [%d]",best);
376
c = DetermineIncrement(m);
385
void GenerateSequence( unsigned int p, unsigned int m,
386
unsigned int a, unsigned int c )
388
register unsigned int i;
389
register unsigned int x;
397
DoubleMultiply(a,x,&d);
399
x = DoubleModulus(&d,m);
404
//**********************************************
405
//***** Member functions from Random class *****
406
//**********************************************
408
OERandom::OERandom(bool useSysRand)
411
this->OERandomUseSysRand= useSysRand;
413
DetermineSequence(p,&m,&a,&c);
417
int OERandom::NextInt()
419
if (OERandomUseSysRand) { return(rand()); }
421
DoubleMultiply(a,x,&d);
423
x = DoubleModulus(&d,m);
429
float OERandom::NextFloat()
432
if (OERandomUseSysRand) { return(float(rand())/float(RAND_MAX)); }
434
DoubleMultiply(a,x,&d);
436
x = DoubleModulus(&d,m);
442
void OERandom::TimeSeed()
445
// for VC++ do it this way
448
const long secs= long(ltime);
450
srand( (unsigned)time( NULL ) );
453
gettimeofday(&time,(struct timezone *)NULL);
454
x = (time.tv_usec%p);