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++) {

Reply via email to