2 * random.c - random number generator for producing mathlib test cases
4 * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
5 * See https://llvm.org/LICENSE.txt for license information.
6 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
12 static uint32 seedbuf
[55];
15 void seed_random(uint32 seed
) {
19 for (i
= 0; i
< 55; i
++) {
20 seed
= seed
% 44488 * 48271 - seed
/ 44488 * 3399;
21 seedbuf
[i
] = seed
- 1;
25 uint32
base_random(void) {
27 seedbuf
[seedptr
] += seedbuf
[(seedptr
+31)%55];
28 return seedbuf
[seedptr
++];
31 uint32
random32(void) {
35 for (b1
= 0x80000000, b2
= 1; b1
> b2
; b1
>>= 1, b2
<<= 1) {
37 if ((b
& b3
) != 0 && (b
& b3
) != b3
)
44 * random_upto: generate a uniformly randomised number in the range
45 * 0,...,limit-1. (Precondition: limit > 0.)
47 * random_upto_biased: generate a number in the same range, but with
48 * the probability skewed towards the high end by means of taking the
49 * maximum of 8*bias+1 samples from the uniform distribution on the
50 * same range. (I don't know why bias is given in that curious way -
51 * historical reasons, I expect.)
53 * For speed, I separate the implementation of random_upto into the
54 * two stages of (a) generate a bitmask which reduces a 32-bit random
55 * number to within a factor of two of the right range, (b) repeatedly
56 * generate numbers in that range until one is small enough. Splitting
57 * it up like that means that random_upto_biased can do (a) only once
58 * even when it does (b) lots of times.
61 static uint32
random_upto_makemask(uint32 limit
) {
62 uint32 mask
= 0xFFFFFFFF;
64 for (i
= 16; i
> 0; i
>>= 1)
65 if ((limit
& (mask
>> i
)) == limit
)
70 static uint32
random_upto_internal(uint32 limit
, uint32 mask
) {
73 ret
= random32() & mask
;
74 } while (ret
> limit
);
78 uint32
random_upto(uint32 limit
) {
79 uint32 mask
= random_upto_makemask(limit
);
80 return random_upto_internal(limit
, mask
);
83 uint32
random_upto_biased(uint32 limit
, int bias
) {
84 uint32 mask
= random_upto_makemask(limit
);
86 uint32 ret
= random_upto_internal(limit
, mask
);
89 tmp
= random_upto_internal(limit
, mask
); if (tmp
< ret
) ret
= tmp
;
90 tmp
= random_upto_internal(limit
, mask
); if (tmp
< ret
) ret
= tmp
;
91 tmp
= random_upto_internal(limit
, mask
); if (tmp
< ret
) ret
= tmp
;
92 tmp
= random_upto_internal(limit
, mask
); if (tmp
< ret
) ret
= tmp
;
93 tmp
= random_upto_internal(limit
, mask
); if (tmp
< ret
) ret
= tmp
;
94 tmp
= random_upto_internal(limit
, mask
); if (tmp
< ret
) ret
= tmp
;
95 tmp
= random_upto_internal(limit
, mask
); if (tmp
< ret
) ret
= tmp
;
96 tmp
= random_upto_internal(limit
, mask
); if (tmp
< ret
) ret
= tmp
;