1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
/* utility.c - burneye2 supporting functions
*
* by scut
*/
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <assert.h>
#include <utility.h>
int quiet = 0;
int rand_fd = -1;
int
fnote (const char *fmt, ...)
{
int len;
va_list ap;
if (quiet)
return (0);
va_start (ap, fmt);
len = vfprintf (stderr, fmt, ap);
va_end (ap);
return (len);
}
void
be_randinit_file (const char *filename)
{
if (rand_fd != -1)
return;
rand_fd = open (filename, 0);
if (rand_fd < 0)
exit (EXIT_FAILURE);
}
void
be_randinit (void)
{
be_randinit_file ("/dev/urandom");
}
void
be_randend (void)
{
close (rand_fd);
rand_fd = -1;
}
unsigned int
be_random (unsigned int max)
{
ssize_t nret;
unsigned int tmp;
if (rand_fd == -1)
be_randinit ();
nret = read (rand_fd, &tmp, sizeof (tmp));
if (nret != sizeof (tmp)) {
if (nret < 0)
perror ("be_random, read random-file");
else
fprintf (stderr, "be_random, random data depleted\n");
exit (EXIT_FAILURE);
}
/* 0 denotes special 0 to 2^32 - 1 range
*/
if (max == 0)
return (tmp);
return (tmp % max);
}
int
be_random_coin (double prob)
{
double rand;
rand = (double) be_random (UINT_MAX);
rand /= (double) UINT_MAX;
if (rand <= prob)
return (1);
return (0);
}
unsigned int
be_random_prob (unsigned int items_count, double *items_prob)
{
double sum = 0.0,
rand;
unsigned int in;
for (in = 0 ; in < items_count ; ++in)
sum += items_prob[in];
in = be_random (UINT_MAX);
rand = in;
rand /= (double) UINT_MAX;
rand *= sum;
sum = 0.0;
for (in = 0 ; sum < rand && in < items_count ; ++in)
sum += items_prob[in];
if (in > 0)
in -= 1;
return (in);
}
|