Fix stuttering sequences and reverse ranges

PR:		123635
Submitted by:	Ulrich Spörlein, uqs at spoerlein dot net
This commit is contained in:
brian 2010-06-02 07:47:29 +00:00
parent 9bef2d9553
commit cb476e3fa5
6 changed files with 140 additions and 10 deletions

View File

@ -0,0 +1,10 @@
0
1
2
3
4
5
6
7
8
9

View File

@ -0,0 +1,10 @@
0
1
2
3
4
5
6
7
8
9

View File

@ -1,6 +1,6 @@
# $FreeBSD$
echo 1..57
echo 1..60
REGRESSION_START($1)
@ -32,12 +32,15 @@ REGRESSION_TEST(`hddd2', `jot 30 - - -')
REGRESSION_TEST(`dhhh2', `jot - 20 160 2')
REGRESSION_TEST(`dhhd2', `jot - 20 160 -')
REGRESSION_TEST(`ddhh2', `jot - - 160 2')
REGRESSION_TEST(`rand1', `jot -r 10000 0 9 | sort -u')
REGRESSION_TEST(`rand2', `jot -r 10000 9 0 | sort -u')
REGRESSION_TEST(`n21', `jot 21 -1 1.00')
REGRESSION_TEST(`ascii', `jot -c 128 0')
REGRESSION_TEST(`xaa', `jot -w xa%c 26 a')
REGRESSION_TEST(`yes', `jot -b yes 10')
REGRESSION_TEST(`ed', `jot -w %ds/old/new/ 30 2 - 5')
REGRESSION_TEST(`stutter', `jot - 9 0 -.5')
REGRESSION_TEST(`stutter2', `jot -w %d - 9.5 0 -.5')
REGRESSION_TEST(`block', `jot -b x 512')
REGRESSION_TEST(`tabs', `jot -s, - 10 132 4')
REGRESSION_TEST(`grep', `jot -s "" -b . 80')

View File

@ -0,0 +1,20 @@
9
9
8
8
7
7
6
6
5
5
4
4
3
3
2
2
1
1
0
0

View File

@ -32,7 +32,7 @@
.\" @(#)jot.1 8.1 (Berkeley) 6/6/93
.\" $FreeBSD$
.\"
.Dd February 19, 2010
.Dd June 2, 2010
.Dt JOT 1
.Os
.Sh NAME
@ -167,6 +167,86 @@ The name
derives in part from
.Nm iota ,
a function in APL.
.Ss Rounding and truncation
The
.Nm
utility uses double precision floating point arithmetic internally.
Before printing a number, it is converted depending on the output
format used.
.Pp
If no output format is specified or the output format is a
floating point format
.Po
.Sq E ,
.Sq G ,
.Sq e ,
.Sq f ,
or
.Sq g
.Pc ,
the value is rounded using the
.Xr printf 3
function, taking into account the requested precision.
.Pp
If the output format is an integer format
.Po
.Sq D ,
.Sq O ,
.Sq U ,
.Sq X ,
.Sq c ,
.Sq d ,
.Sq i ,
.Sq o ,
.Sq u ,
or
.Sq x
.Pc ,
the value is converted to an integer value by truncation.
.Pp
As an illustration, consider the following command:
.Bd -literal -offset indent
$ jot 6 1 10 0.5
1
2
2
2
3
4
.Ed
.Pp
By requesting an explicit precision of 1, the values generated before rounding
can be seen.
The .5 values are rounded down if the integer part is even,
up otherwise.
.Bd -literal -offset indent
$ jot -p 1 6 1 10 0.5
1.0
1.5
2.0
2.5
3.0
3.5
.Ed
.Pp
By offsetting the values slightly, the values generated by the following
command are always rounded down:
.Bd -literal -offset indent
$ jot -p 0 6 .9999999999 10 0.5
1
1
2
2
3
3
.Ed
.Pp
Another way of achieving the same result is to force truncation by
specifying an integer format:
.Bd -literal -offset indent
$ jot -w %d 6 1 10 0.5
.Ed
.Pp
.Sh EXIT STATUS
.Ex -std
.Sh EXAMPLES
@ -201,9 +281,9 @@ the result of
.Dl jot -w %ds/old/new/ 30 2 - 5
.Pp
The stuttering sequence 9, 9, 8, 8, 7, etc.\& can be
produced by suitable choice of step size,
produced by truncating the output precision and a suitable choice of step size,
as in
.Dl jot - 9 0 -.5
.Dl jot -w %d - 9.5 0 -.5
.Pp
and a file containing exactly 1024 bytes is created with
.Dl jot -b x 512 > block

View File

@ -77,7 +77,7 @@ __FBSDID("$FreeBSD$");
#define is_default(s) (*(s) == 0 || strcmp((s), "-") == 0)
static bool boring;
static int prec;
static int prec = -1;
static bool longdata;
static bool intdata;
static bool chardata;
@ -128,7 +128,7 @@ main(int argc, char **argv)
break;
case 'p':
prec = atoi(optarg);
if (prec <= 0)
if (prec < 0)
errx(1, "bad precision value");
have_format = true;
break;
@ -159,7 +159,7 @@ main(int argc, char **argv)
if (!sscanf(argv[2], "%lf", &ender))
ender = argv[2][strlen(argv[2])-1];
mask |= HAVE_ENDER;
if (!prec)
if (prec < 0)
n = getprec(argv[2]);
}
/* FALLTHROUGH */
@ -168,7 +168,7 @@ main(int argc, char **argv)
if (!sscanf(argv[1], "%lf", &begin))
begin = argv[1][strlen(argv[1])-1];
mask |= HAVE_BEGIN;
if (!prec)
if (prec < 0)
prec = getprec(argv[1]);
if (n > prec) /* maximum precision */
prec = n;
@ -188,6 +188,10 @@ main(int argc, char **argv)
argv[4]);
}
getformat();
if (prec == -1)
prec = 0;
while (mask) /* 4 bit mask has 1's where last 4 args were given */
switch (mask) { /* fill in the 0's by default or computation */
case HAVE_STEP:
@ -284,13 +288,16 @@ main(int argc, char **argv)
if (!have_format && prec == 0 &&
begin >= 0 && begin < divisor &&
ender >= 0 && ender < divisor) {
ender += 1;
if (begin <= ender)
ender += 1;
else
begin += 1;
nosign = true;
intdata = true;
(void)strlcpy(format,
chardata ? "%c" : "%u", sizeof(format));
}
x = (ender - begin) * (ender > begin ? 1 : -1);
x = ender - begin;
for (i = 1; i <= reps || infinity; i++) {
if (use_random)
y = random() / divisor;