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"); > > >