On Sat, Jul 16, 2016 at 09:46:29PM +0200, Theo Buehler wrote: > I see two options apart from reverting my commit. > > 1. Just fix the bug Otto noticed. Remove the section on randomness > completely and fix one example in the manual. That's what the patch > in this mail does. The patch for jot.c is the same as in my previous > mail. > > 2. Restore the previous behavior when -w or -c is specified together > with -r and fix the bug Otto noticed. I will send this patch in a > second mail. > > sobrado@ and I checked that this patch would match the behavior of Linux > and NetBSD. In particular, the format string does not change the output > drastically: > > $ jot -r 100000 1 3 | sort -n | uniq -c > 33148 1 > 33452 2 > 33400 3 > $ jot -w %d -r 100000 1 3 | sort -n | uniq -c > 33373 1 > 33239 2 > 33388 3 > > I think this behavior makes sense: if the output consists of integers > anyway, then a %d format should not alter it, independently of what > happens under the hood. > > The downside is that it breaks scripts that relied on the previous > behavior that was explicitly mentioned in the manual (as Philippe found > the hard way; sorry about that!). >
i know we need to tread carefully with breaking scripts, but i think the balance is that we need a sane world too. i think we should take the stand for simplicity and sanity (option 1). ok for the man page. jmc > Index: jot.1 > =================================================================== > RCS file: /var/cvs/src/usr.bin/jot/jot.1,v > retrieving revision 1.19 > diff -u -p -r1.19 jot.1 > --- jot.1 4 Jan 2016 23:21:28 -0000 1.19 > +++ jot.1 16 Jul 2016 19:09:59 -0000 > @@ -225,41 +225,6 @@ specifying an integer format: > .Bd -literal -offset indent > $ jot -w %d 6 1 10 0.5 > .Ed > -.Pp > -For random sequences, the output format also influences the range > -and distribution of the generated numbers: > -.Bd -literal -offset indent > -$ jot -r 100000 1 3 | sort -n | uniq -c > -24950 1 > -50038 2 > -25012 3 > -.Ed > -.Pp > -The values at the beginning and end of the interval > -are generated less frequently than the other values. > -There are several ways to solve this problem and generate evenly distributed > -integers: > -.Bd -literal -offset indent > -$ jot -r -p 0 100000 0.5 3.5 | sort -n | uniq -c > -33374 1 > -33363 2 > -33263 3 > - > -$ jot -w %d -r 100000 1 4 | sort -n | uniq -c > -33306 1 > -33473 2 > -33221 3 > -.Ed > -.Pp > -Note that with random sequences, all numbers generated will > -be smaller than the upper bound. > -The largest value generated will be a tiny bit smaller than > -the upper bound. > -For floating point formats, the value is rounded as described > -before being printed. > -For integer formats, the highest value printed will be one less > -than the requested upper bound, because the generated value will > -be truncated. > .Sh EXAMPLES > Print 21 evenly spaced numbers increasing from \-1 to 1: > .Pp > @@ -280,7 +245,7 @@ comes after the character > .Sq z > in the ASCII character set): > .Pp > -.Dl "$ jot \-r \-c 160 a { | rs \-g0 0 8" > +.Dl "$ jot \-r \-c 160 a z | rs \-g0 0 8" > .Pp > Infinitely many > .Xr yes 1 Ns 's > Index: jot.c > =================================================================== > RCS file: /var/cvs/src/usr.bin/jot/jot.c,v > retrieving revision 1.27 > diff -u -p -r1.27 jot.c > --- jot.c 10 Jan 2016 01:15:52 -0000 1.27 > +++ jot.c 16 Jul 2016 19:10:18 -0000 > @@ -277,9 +277,6 @@ main(int argc, char *argv[]) > if (prec > 9) /* pow(10, prec) > UINT32_MAX */ > errx(1, "requested precision too large"); > > - while (prec-- > 0) > - pow10 *= 10; > - > if (ender < begin) { > x = begin; > begin = ender; > @@ -287,16 +284,22 @@ main(int argc, char *argv[]) > } > x = ender - begin; > > - /* > - * If pow10 * (ender - begin) is an integer, use > - * arc4random_uniform(). > - */ > - use_unif = fmod(pow10 * (ender - begin), 1) == 0; > - if (use_unif) { > - uintx = pow10 * (ender - begin); > - if (uintx >= UINT32_MAX) > - errx(1, "requested range too large"); > - uintx++; > + if (prec == 0 && (fmod(ender, 1) != 0 || fmod(begin, 1) != 0)) > + use_unif = 0; > + else { > + while (prec-- > 0) > + pow10 *= 10; > + /* > + * If pow10 * (ender - begin) is an integer, use > + * arc4random_uniform(). > + */ > + use_unif = fmod(pow10 * (ender - begin), 1) == 0; > + if (use_unif) { > + uintx = pow10 * (ender - begin); > + if (uintx >= UINT32_MAX) > + errx(1, "requested range too large"); > + uintx++; > + } > } > > for (i = 1; i <= reps || infinity; i++) {