I'm not sure about the tradeoff in this approach.

Won't the lack of precision in double eventually lead to non-uniformity?

The way jot is written, I expect higher ranges to have lots of
non-uniformity unless a substantial rewrite is undertaken, but I am
worry your approach creates non-uniformity within the 32-bit range.

alf <a.schlicht...@lemarit.com> wrote:

> Hello,
> 
> jot(1) appears to give unsatisfying randomness when used 
> with larger numbers (and -r):
> 
> # (before diff)
> % jot -r 10 1000000000 9999999999
> 1294196288
> 1351335130
> 1105868309
> 1082237294
> 1078729542
> 1009152305
> 1108537886
> 1362127442
> 1071708731
> 1402965187
> 
> That is because in jot.c we see:
> 
> 249           uint32_t        uintx = 0; /* Initialized to make gcc happy. */
>               ...
> 
> 272                           uintx = pow10 * (ender - begin);
> 273                           if (uintx >= UINT32_MAX)
> 274                                   errx(1, "requested range too large");
>               ...
> 
> Later on uintx is used like this:
>               ...
> 283                           y = arc4random_uniform(uintx) / (double)pow10;
>               ...
> 
> Changing uintx to double fixes the issue for me (the error-condition
> triggers) and it passes the tests in regress/usr.bin/jot, however 
> may not be the proper fix.
> 
> #(after diff)
> % jot -r 10 1000000000 9999999999
> jot: requested range too large
> 
> Alf
> 
> 
> Index: usr.bin/jot/jot.c
> ===================================================================
> RCS file: /cvs/src/usr.bin/jot/jot.c,v
> retrieving revision 1.49
> diff -u -p -r1.49 jot.c
> --- usr.bin/jot/jot.c 27 Jun 2019 18:03:36 -0000      1.49
> +++ usr.bin/jot/jot.c 29 Jul 2021 09:12:22 -0000
> @@ -246,7 +246,7 @@ main(int argc, char *argv[])
>       } else { /* Random output: use defaults for omitted values. */
>               bool            use_unif;
>               uint32_t        pow10 = 1;
> -             uint32_t        uintx = 0; /* Initialized to make gcc happy. */
> +             double          uintx = 0; /* Initialized to make gcc happy. */
>  
>               if (prec > 9)   /* pow(10, prec) > UINT32_MAX */
>                       errx(1, "requested precision too large");
> 
> 
> 

Reply via email to