summaryrefslogtreecommitdiffstats
path: root/usr.bin
diff options
context:
space:
mode:
authordds <dds@FreeBSD.org>2006-11-06 13:55:11 +0000
committerdds <dds@FreeBSD.org>2006-11-06 13:55:11 +0000
commitc15edb9d96dd6a4461bd687f8dc8ad5388b02f02 (patch)
treee0b79f484145bfec4ce6f98acde0e8d2fe8ce25b /usr.bin
parent13dc4f1b111e5d9cb42399807ff15d52a0b75793 (diff)
downloadFreeBSD-src-c15edb9d96dd6a4461bd687f8dc8ad5388b02f02.zip
FreeBSD-src-c15edb9d96dd6a4461bd687f8dc8ad5388b02f02.tar.gz
Do What I Mean when the user asks for random integers or characters.
Up to now jot would fail to generate the last character in the range or skew the integer distribution in a way that would generate the numbers in the range's limits with half the probability of the rest. This modification fixes the program, rather than documenting the strange behavior, as suggested in docs/54879. Also, correctly specify the range of random(3). PR: docs/54879 MFC after: 2 weeks
Diffstat (limited to 'usr.bin')
-rw-r--r--usr.bin/jot/jot.119
-rw-r--r--usr.bin/jot/jot.c39
2 files changed, 50 insertions, 8 deletions
diff --git a/usr.bin/jot/jot.1 b/usr.bin/jot/jot.1
index e1e98ac..1aa0d62 100644
--- a/usr.bin/jot/jot.1
+++ b/usr.bin/jot/jot.1
@@ -32,7 +32,7 @@
.\" @(#)jot.1 8.1 (Berkeley) 6/6/93
.\" $FreeBSD$
.\"
-.Dd June 6, 1993
+.Dd November 6, 2006
.Dt JOT 1
.Os
.Sh NAME
@@ -145,6 +145,23 @@ when no seed is specified,
and through
.Xr random 3
when a seed is given.
+When
+.Nm
+is asked to generate random integers or characters with begin
+and end values in the range of the random number generator function
+and no format is specified with one of the
+.Fl w ,
+.Fl b ,
+or
+.Fl p
+options,
+.Nm
+will arrange for all the values in the range to appear in the output
+with an equal probability.
+In all other cases be careful to ensure that the output format's
+rounding or truncation will not skew the distribution of output
+values in an unintended way.
+.Pp
The name
.Nm
derives in part from
diff --git a/usr.bin/jot/jot.c b/usr.bin/jot/jot.c
index 1464e4d..d7f700c 100644
--- a/usr.bin/jot/jot.c
+++ b/usr.bin/jot/jot.c
@@ -103,7 +103,9 @@ main(int argc, char **argv)
unsigned int mask = 0;
int n = 0;
int ch;
- bool have_seed = false;
+ bool use_random = false;
+ bool have_format = false;
+ double divisor;
while ((ch = getopt(argc, argv, "rb:w:cs:np:")) != -1)
switch (ch) {
@@ -123,6 +125,7 @@ main(int argc, char **argv)
if (strlcpy(format, optarg, sizeof(format)) >=
sizeof(format))
errx(1, "-%c word too long", ch);
+ have_format = true;
break;
case 's':
sepstring = optarg;
@@ -131,6 +134,7 @@ main(int argc, char **argv)
prec = atoi(optarg);
if (prec <= 0)
errx(1, "bad precision value");
+ have_format = true;
break;
default:
usage();
@@ -145,7 +149,7 @@ main(int argc, char **argv)
errx(1, "bad s value: %s", argv[3]);
mask |= HAVE_STEP;
if (randomize)
- have_seed = true;
+ use_random = true;
}
/* FALLTHROUGH */
case 3:
@@ -258,14 +262,35 @@ main(int argc, char **argv)
if (reps == 0)
infinity = 1;
if (randomize) {
- x = (ender - begin) * (ender > begin ? 1 : -1);
- if (have_seed)
+ if (use_random) {
srandom((unsigned long)s);
+ divisor = (double)INT32_MAX + 1;
+ } else
+ divisor = (double)UINT32_MAX + 1;
+
+ /*
+ * Attempt to DWIM when the user has specified an
+ * integer range within that of the random number
+ * generator: distribute the numbers equally in
+ * the range [begin .. ender]. Jot's default %.0f
+ * format would make the appearance of the first and
+ * last specified value half as likely as the rest.
+ */
+ if (!have_format && prec == 0 &&
+ begin >= 0 && begin < divisor &&
+ ender >= 0 && ender < divisor) {
+ ender += 1;
+ nosign = 1;
+ intdata = 1;
+ (void)strlcpy(format,
+ chardata ? "%c" : "%u", sizeof(format));
+ }
+ x = (ender - begin) * (ender > begin ? 1 : -1);
for (i = 1; i <= reps || infinity; i++) {
- if (have_seed)
- y = random() / ((double)LONG_MAX + 1);
+ if (use_random)
+ y = random() / divisor;
else
- y = arc4random() / ((double)UINT32_MAX + 1);
+ y = arc4random() / divisor;
if (putdata(y * x + begin, reps - i))
errx(1, "range error in conversion");
}
OpenPOWER on IntegriCloud