> The second exmaple: > > $ jot -r -p 0 100000 0.5 3.5 | sort -n | uniq -c > 25120 0 > 49882 2 > 24998 4 > > So I'd says there are real bugs introduced with the latest commit. > > -Otto >
Indeed, this is bad. The following patch lets the code fall back to the old version in the cases that the new code doesn't handle well: As we discussed on icb, if -p 0 is given, only use the new code if both endpoints are integers seems to work nicely. $ jot -r -p 0 100000 0.5 3.5 | sort -n | uniq -c 33434 1 33228 2 33338 3 $ jot -r -p 0 100000 1 3 | sort -n | uniq -c 33464 1 33246 2 33290 3 Bad bias in some cases is unavoidable: $ jot -r -p 0 100000 1 3.5 | sort -n | uniq -c 19923 1 39934 2 40143 3 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 15 Jul 2016 06:26:29 -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++) {