/*** | |
| Code to implement random() & srandom() of BSD Unix. It was taken
(though coded somewhat differently) from the Gnu BSD implementation. |
***/ | |
#include <stdio.h> |
#include <stdlib.h> |
|
#ifdef LONG31 /* x^31 + x^3 + 1 */ |
#define SIZE 31 |
#define SIZE1 30 |
#define P1 3 |
#define P2 0 |
#else /* LONG63: x^63 + x + 1 */ |
#define SIZE 63 |
#define SIZE1 62 |
#define P1 1 |
#define P2 0 |
#endif |
|
#define LONG_MAX 0x7fffffff |
|
int p1=P1, p2=P2; |
long table[SIZE]; |
|
/*** return a "random" number in range [0, LONG_MAX] */ |
long xrand () |
{ |
| int r; |
|
| table[p1] = table[p1] + table[p2]; /* add two table elements */ |
| r = (table[p1] >> 1) & LONG_MAX; /* throw least significant bit away */ |
|
| if (p1 == SIZE1) { /* increment the table indexes */ |
| | p1 = 0; |
| p2 = p2 + 1; |
| } |
| else if (p2 == SIZE1) { |
| p1 = p1 + 1; |
| p2 = 0; |
| } |
| else { |
| p1 = p1 + 1; |
| p2 = p2 + 1; |
| } |
|
| return (r); |
} |
|
|
/*** | |
| use a linear congruential type generator to seed the
state table & cycle the entire table 10 times |
***/ | |
void sxrand (seed)
|
long seed; |
{ |
| int i; |
|
| table[0] = seed; |
| for (i=1; i<SIZE; ++i) |
| table[i] = (table[i-1] * 1103515145) + 12345; /* lousy */ |
|
| for (i=0; i<10*SIZE; ++i) |
| (void) xrand(); |
} |
|
|
/*** a small test program ***/ |
void main () |
{ |
| int i; |
|
| sxrand (1); /* BSD default */ |
|
| for (i=1; i<=40; ++i) |
| printf ("%ld", xrand() % 10 ); /* least random bits ? */ |
|
| /* 6714066113586447326208220248220881760069 (cc -DLONG63) */ |
| /* 9418752338157675324663485137890734831064 (cc -DLONG31) */ |
|
| printf ("\n"); |
} |