1 | /* |
---|
2 | * |
---|
3 | * Rand.c |
---|
4 | * |
---|
5 | * - linear and additive congruential random number generators |
---|
6 | * (see R. Sedgewick, Algorithms, Chapter 35) |
---|
7 | * |
---|
8 | * Implementation: R. Fuchs, EMBL Data Library, 1991 |
---|
9 | * |
---|
10 | */ |
---|
11 | #include <stdio.h> |
---|
12 | |
---|
13 | unsigned long linrand(unsigned long r); |
---|
14 | unsigned long addrand(unsigned long r); |
---|
15 | void addrandinit(unsigned long s); |
---|
16 | |
---|
17 | static unsigned long mult(unsigned long p,unsigned long q); |
---|
18 | |
---|
19 | |
---|
20 | #define m1 10000 |
---|
21 | #define m 100000000 |
---|
22 | |
---|
23 | static unsigned long mult(unsigned long p, unsigned long q); |
---|
24 | |
---|
25 | /* linear congruential method |
---|
26 | * |
---|
27 | * linrand() returns an unsigned long random number in the range 0 to r-1 |
---|
28 | */ |
---|
29 | |
---|
30 | |
---|
31 | unsigned long linrand(unsigned long r) |
---|
32 | { |
---|
33 | static unsigned long a=1234567; |
---|
34 | |
---|
35 | a = (mult(a,31415821)+1) % m; |
---|
36 | return( ( (a / m1) * r) / m1 ); |
---|
37 | } |
---|
38 | |
---|
39 | static unsigned long mult(unsigned long p, unsigned long q) |
---|
40 | { |
---|
41 | unsigned long p1,p0,q1,q0; |
---|
42 | |
---|
43 | p1 = p/m1; p0 = p % m1; |
---|
44 | q1 = q/m1; q0 = q % m1; |
---|
45 | return((((p0*q1 + p1*q0) % m1) * m1 + p0*q0) % m); |
---|
46 | } |
---|
47 | |
---|
48 | |
---|
49 | /* additive congruential method |
---|
50 | * |
---|
51 | * addrand() returns an unsigned long random number in the range 0 to r-1 |
---|
52 | * The random number generator is initialized by addrandinit() |
---|
53 | */ |
---|
54 | |
---|
55 | static unsigned long j; |
---|
56 | static unsigned long a[55]; |
---|
57 | |
---|
58 | unsigned long addrand(unsigned long r) |
---|
59 | { |
---|
60 | int x,y; |
---|
61 | /* fprintf(stdout,"\n j = %d",j); */ |
---|
62 | j = (j + 1) % 55; |
---|
63 | /* fprintf(stdout,"\n j = %d",j); */ |
---|
64 | x = (j+23)%55; |
---|
65 | y = (j+54)%55; |
---|
66 | a[j] = (a[x] + a[y]) % m; |
---|
67 | /* a[j] = (a[(j+23)%55] + a[(j+54)%55]) % m; */ |
---|
68 | /* fprintf(stdout,"\n a[j] = %d",a[j]); */ |
---|
69 | return( ((a[j] / m1) * r) / m1 ); |
---|
70 | } |
---|
71 | |
---|
72 | void addrandinit(unsigned long s) |
---|
73 | { |
---|
74 | a[0] = s; |
---|
75 | j = 0; |
---|
76 | do { |
---|
77 | ++j; |
---|
78 | a[j] = (mult(31,a[j-1]) + 1) % m; |
---|
79 | } while (j<54); |
---|
80 | } |
---|
81 | |
---|