generic/192: fix instability on exFAT
[xfstests-dev.git] / lib / random.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * random.c -- pseudo random number generator
4  * Copyright (C) 1994  Chris Wallace (csw@bruce.cs.monash.edu.au)
5  */
6
7 #include <sys/types.h>
8
9 /*
10  * modified by dxm@sgi.com so that this file acts as a drop in replacement
11  * for srandom and random.
12  */
13
14 /*
15  *      A random number generator called as a function by
16  *      random (iseed)  or      irandm (iseed)
17  *      The parameter should be a pointer to a 2-element int32_t vector.
18  *      The first function returns a double uniform in 0 .. 1.
19  *      The second returns a int32_t integer uniform in 0 .. 2**31-1
20  *      Both update iseed[] in exactly the same way.
21  *      iseed[] must be a 2-element integer vector.
22  *      The initial value of the second element may be anything.
23  *
24  *      The period of the random sequence is 2**32 * (2**32-1)
25  *      The table mt[0:127] is defined by mt[i] = 69069 ** (128-i)
26  */
27
28 #define MASK ((int32_t) 593970775)
29 /*      or in hex, 23674657     */
30
31 #define SCALE ((double) 1.0 / (1024.0 * 1024.0 * 1024.0 * 2.0))
32 /*      i.e. 2 to power -31     */
33
34 static int32_t mt [128] =   {
35       902906369,
36      2030498053,
37      -473499623,
38      1640834941,
39       723406961,
40      1993558325,
41      -257162999,
42     -1627724755,
43       913952737,
44       278845029,
45      1327502073,
46     -1261253155,
47       981676113,
48     -1785280363,
49      1700077033,
50       366908557,
51     -1514479167,
52      -682799163,
53       141955545,
54      -830150595,
55       317871153,
56      1542036469,
57      -946413879,
58     -1950779155,
59       985397153,
60       626515237,
61       530871481,
62       783087261,
63     -1512358895,
64      1031357269,
65     -2007710807,
66     -1652747955,
67     -1867214463,
68       928251525,
69      1243003801,
70     -2132510467,
71      1874683889,
72      -717013323,
73       218254473,
74     -1628774995,
75     -2064896159,
76        69678053,
77       281568889,
78     -2104168611,
79      -165128239,
80      1536495125,
81       -39650967,
82       546594317,
83      -725987007,
84      1392966981,
85      1044706649,
86       687331773,
87     -2051306575,
88      1544302965,
89      -758494647,
90     -1243934099,
91       -75073759,
92       293132965,
93     -1935153095,
94       118929437,
95       807830417,
96     -1416222507,
97     -1550074071,
98       -84903219,
99      1355292929,
100      -380482555,
101     -1818444007,
102      -204797315,
103       170442609,
104     -1636797387,
105       868931593,
106      -623503571,
107      1711722209,
108       381210981,
109      -161547783,
110      -272740131,
111     -1450066095,
112      2116588437,
113      1100682473,
114       358442893,
115     -1529216831,
116      2116152005,
117      -776333095,
118      1265240893,
119      -482278607,
120      1067190005,
121       333444553,
122        86502381,
123       753481377,
124        39000101,
125      1779014585,
126       219658653,
127      -920253679,
128      2029538901,
129      1207761577,
130     -1515772851,
131      -236195711,
132       442620293,
133       423166617,
134     -1763648515,
135      -398436623,
136     -1749358155,
137      -538598519,
138      -652439379,
139       430550625,
140     -1481396507,
141      2093206905,
142     -1934691747,
143      -962631983,
144      1454463253,
145     -1877118871,
146      -291917555,
147     -1711673279,
148       201201733,
149      -474645415,
150       -96764739,
151     -1587365199,
152      1945705589,
153      1303896393,
154      1744831853,
155       381957665,
156      2135332261,
157       -55996615,
158     -1190135011,
159      1790562961,
160     -1493191723,
161       475559465,
162           69069
163                 };
164
165 double 
166 _random (int32_t is [2])
167 {
168         int32_t it, leh, nit;
169
170         it = is [0];
171         leh = is [1];
172         if (it <= 0)    
173                 it = (it + it) ^ MASK;
174         else
175                 it = it + it;
176         nit = it - 1;
177 /*      to ensure all-ones pattern omitted    */
178         leh = leh * mt[nit & 127] + nit;
179         is [0] = it;    is [1] = leh;
180         if (leh < 0) leh = ~leh;
181         return (SCALE * ((int32_t) (leh | 1)));
182 }
183
184
185
186 int32_t 
187 _irandm (int32_t is [2])
188 {
189         int32_t it, leh, nit;
190
191         it = is [0];
192         leh = is [1];
193         if (it <= 0)    
194                 it = (it + it) ^ MASK;
195         else
196                 it = it + it;
197         nit = it - 1;
198 /*      to ensure all-ones pattern omitted    */
199         leh = leh * mt[nit & 127] + nit;
200         is [0] = it;    is [1] = leh;
201         if (leh < 0) leh = ~leh;
202         return (leh);
203 }
204
205 /*
206  * make this a drop in replacement for random and srandom
207  *
208  * XXX not thread safe I guess.
209  */
210
211 static int32_t saved_seed[2];
212
213 long random(void)
214 {
215     return _irandm(saved_seed);
216 }
217
218 void srandom(unsigned seed)
219 {
220     saved_seed[0]=seed;
221     saved_seed[1]=0;
222     _irandm(saved_seed);
223 }
224