From nobody@FreeBSD.org  Tue May 13 18:15:56 2008
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 2F22B106564A
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 13 May 2008 18:15:56 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 1DA5D8FC1B
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 13 May 2008 18:15:56 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.2/8.14.2) with ESMTP id m4DIEmKv079754
	for <freebsd-gnats-submit@FreeBSD.org>; Tue, 13 May 2008 18:14:48 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.2/8.14.1/Submit) id m4DIEmhL079753;
	Tue, 13 May 2008 18:14:48 GMT
	(envelope-from nobody)
Message-Id: <200805131814.m4DIEmhL079753@www.freebsd.org>
Date: Tue, 13 May 2008 18:14:48 GMT
From: Elias Pipping <elias@pipping.org>
To: freebsd-gnats-submit@FreeBSD.org
Subject: jot handles 'stuttering sequences' and reversed ranges incorrectly
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         123635
>Category:       bin
>Synopsis:       jot(1) handles 'stuttering sequences' and reversed ranges incorrectly
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    brian
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue May 13 18:20:01 UTC 2008
>Closed-Date:    Fri Jun 18 07:20:31 UTC 2010
>Last-Modified:  Fri Jun 18 07:20:31 UTC 2010
>Originator:     Elias Pipping
>Release:        current
>Organization:
>Environment:
The tests were run on an intel mac with the /usr.bin/jot code from CVS

$ uname -a
Darwin mac.local 9.2.2 Darwin Kernel Version 9.2.2: Tue Mar  4 21:17:34 PST 2008; root:xnu-1228.4.31~1/RELEASE_I386 i386
>Description:
Jot does not seem to be working correctly, with regard to both intuition
and to the manpage.

I'll use pp.awk to format the output of jot a bit -- you can find the
code further down.

The manpage suggests:

  The stuttering sequence 9, 9, 8, 8, 7, etc. can be produced by
  suitable choice of step size, as in
     jot - 9 0 -.5

This is what happens:

  $ jot - 9 0 -.5 | awk -f pp.awk
     2    3    4    5    6    7    8    9    0    1
     3    1    3    1    3    1    3    1    2    1

Furthermore, while this works:

  $ jot -r 10000 0 9 | awk -f pp.awk
     2    3    4    5    6    7    8    9    0    1
   999  977 1008  972  989 1007 1006 1053 1032  957

This should produce basically the same results, but it does not:

  $ jot -r 10000 9 0 | awk -f pp.awk
     9   10   11   12   13   14   15   16
  1237 1233 1271 1210 1247 1260 1262 1280


Appendix
========

$ cat pp.awk
{
  freq[$0]++
}

END \
{
  for (entry in freq)
    printf("%4s ", entry);
  print("");
  for (entry in freq)
    printf("%4d ", freq[entry]);
  print("");
}
>How-To-Repeat:
This script

  http://page.mi.fu-berlin.de/pipping/jot/test_jot.sh

runs a couple of tests with jot fetched from multiple BSDs' CVS repositories. (Tested on Mac OS X only)
>Fix:


>Release-Note:
>Audit-Trail:

From: Ulrich =?utf-8?B?U3DDtnJsZWlu?= <uqs@spoerlein.net>
To: Elias Pipping <elias@pipping.org>
Cc: bug-followup@FreeBSD.org, brian@FreeBSD.org
Subject: Re: bin/123635: jot handles 'stuttering sequences' and reversed
 ranges incorrectly
Date: Sun, 12 Jul 2009 16:31:29 +0200

 --EVF5PPMfhYS0aIcm
 Content-Type: text/plain; charset=us-ascii
 Content-Disposition: inline
 
 On Tue, 13.05.2008 at 18:14:48 +0000, Elias Pipping wrote:
 > The manpage suggests:
 > 
 >   The stuttering sequence 9, 9, 8, 8, 7, etc. can be produced by
 >   suitable choice of step size, as in
 >      jot - 9 0 -.5
 > 
 > This is what happens:
 > 
 >   $ jot - 9 0 -.5 | awk -f pp.awk
 >      2    3    4    5    6    7    8    9    0    1
 >      3    1    3    1    3    1    3    1    2    1
 
 True, this is because jot(1)'s default output format is "%.0f" and the
 sequence 9.0, 8.5, 8.0, 7.5, etc is rounded "weird". This is no bug in
 jot(1) however, but has to do with floating point precision. To work
 around this, you can pass -w %d which forces different kind of rounding.
 
 % jot -w %d - 9 0 -.5 | awk -f pp.awk
    2    3    4    5    6    7    8    9    0    1 
    2    2    2    2    2    2    2    1    2    2 
 
 > Furthermore, while this works:
 > 
 >   $ jot -r 10000 0 9 | awk -f pp.awk
 >      2    3    4    5    6    7    8    9    0    1
 >    999  977 1008  972  989 1007 1006 1053 1032  957
 > 
 > This should produce basically the same results, but it does not:
 > 
 >   $ jot -r 10000 9 0 | awk -f pp.awk
 >      9   10   11   12   13   14   15   16
 >   1237 1233 1271 1210 1247 1260 1262 1280
 
 This is indeed a bug. Please see the attached patch, which fixes this:
 
 % jot -r 10000 9 0 | awk -f pp.awk
    2    3    4    5    6    7    8    9    0    1 
 1021  974  979 1002  975 1030 1019  990  997 1013 
 % jot -r 10000 0 9 | awk -f pp.awk
    2    3    4    5    6    7    8    9    0    1 
 1013  974  978  996  990  970 1034  988 1036 1021 
 
 The patch does the following:
 
 - fix -r mode when begin>ender (the scale x then shall be negative!)
 - allow forcing precision to 0 like NetBSD/OpenBSD do
 - steal man-page section "Rounding and truncation" from OpenBSD
 - fix "stuttering sequence" example in manpage
 - add regression tests
 
 
 --EVF5PPMfhYS0aIcm
 Content-Type: text/x-diff; charset=us-ascii
 Content-Disposition: attachment; filename="jot.diff"
 
 Index: usr.bin/jot/jot.1
 ===================================================================
 --- usr.bin/jot/jot.1	(revision 195633)
 +++ usr.bin/jot/jot.1	(working copy)
 @@ -32,7 +32,7 @@
  .\"	@(#)jot.1	8.1 (Berkeley) 6/6/93
  .\" $FreeBSD$
  .\"
 -.Dd November 6, 2006
 +.Dd July 12, 2009
  .Dt JOT 1
  .Os
  .Sh NAME
 @@ -167,6 +167,86 @@
  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 @@
  .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
 Index: usr.bin/jot/jot.c
 ===================================================================
 --- usr.bin/jot/jot.c	(revision 195633)
 +++ usr.bin/jot/jot.c	(working copy)
 @@ -77,7 +77,7 @@
  #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 @@
  			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 @@
  			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 @@
  			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 @@
  		    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 @@
  		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;
 Index: tools/regression/usr.bin/jot/regress.sh
 ===================================================================
 --- tools/regression/usr.bin/jot/regress.sh	(revision 195633)
 +++ tools/regression/usr.bin/jot/regress.sh	(working copy)
 @@ -1,6 +1,6 @@
  # $FreeBSD$
  
 -echo 1..57
 +echo 1..60
  
  REGRESSION_START($1)
  
 @@ -32,12 +32,15 @@
  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')
 Index: tools/regression/usr.bin/jot/regress.rand1.out
 ===================================================================
 --- tools/regression/usr.bin/jot/regress.rand1.out	(revision 0)
 +++ tools/regression/usr.bin/jot/regress.rand1.out	(revision 0)
 @@ -0,0 +1,10 @@
 +0
 +1
 +2
 +3
 +4
 +5
 +6
 +7
 +8
 +9
 Index: tools/regression/usr.bin/jot/regress.rand2.out
 ===================================================================
 --- tools/regression/usr.bin/jot/regress.rand2.out	(revision 0)
 +++ tools/regression/usr.bin/jot/regress.rand2.out	(revision 0)
 @@ -0,0 +1,10 @@
 +0
 +1
 +2
 +3
 +4
 +5
 +6
 +7
 +8
 +9
 Index: tools/regression/usr.bin/jot/regress.stutter2.out
 ===================================================================
 --- tools/regression/usr.bin/jot/regress.stutter2.out	(revision 0)
 +++ tools/regression/usr.bin/jot/regress.stutter2.out	(revision 0)
 @@ -0,0 +1,20 @@
 +9
 +9
 +8
 +8
 +7
 +7
 +6
 +6
 +5
 +5
 +4
 +4
 +3
 +3
 +2
 +2
 +1
 +1
 +0
 +0
 
 --EVF5PPMfhYS0aIcm--
Responsible-Changed-From-To: freebsd-bugs->brian 
Responsible-Changed-By: brian 
Responsible-Changed-When: Mon Aug 3 11:04:41 UTC 2009 
Responsible-Changed-Why:  
Ulrich asked me to have a look at committing this (maybe after 8.0 
is released). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=123635 
State-Changed-From-To: open->patched 
State-Changed-By: brian 
State-Changed-When: Wed Jun 2 07:38:53 UTC 2010 
State-Changed-Why:  
Committed to -current.  I'll request re@ approval to MFC to 8 
in two weeks, but as we're in code freeze, the MFC may have to 
wait 'till 8.1 is released. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=123635 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/123635: commit references a PR
Date: Wed,  2 Jun 2010 07:47:38 +0000 (UTC)

 Author: brian
 Date: Wed Jun  2 07:47:29 2010
 New Revision: 208728
 URL: http://svn.freebsd.org/changeset/base/208728
 
 Log:
   Fix stuttering sequences and reverse ranges
   
   PR:		123635
   Submitted by:	Ulrich Spörlein, uqs at spoerlein dot net
 
 Added:
   head/tools/regression/usr.bin/jot/regress.rand1.out   (contents, props changed)
   head/tools/regression/usr.bin/jot/regress.rand2.out   (contents, props changed)
   head/tools/regression/usr.bin/jot/regress.stutter2.out   (contents, props changed)
 Modified:
   head/tools/regression/usr.bin/jot/regress.sh
   head/usr.bin/jot/jot.1
   head/usr.bin/jot/jot.c
 
 Added: head/tools/regression/usr.bin/jot/regress.rand1.out
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/regression/usr.bin/jot/regress.rand1.out	Wed Jun  2 07:47:29 2010	(r208728)
 @@ -0,0 +1,10 @@
 +0
 +1
 +2
 +3
 +4
 +5
 +6
 +7
 +8
 +9
 
 Added: head/tools/regression/usr.bin/jot/regress.rand2.out
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/regression/usr.bin/jot/regress.rand2.out	Wed Jun  2 07:47:29 2010	(r208728)
 @@ -0,0 +1,10 @@
 +0
 +1
 +2
 +3
 +4
 +5
 +6
 +7
 +8
 +9
 
 Modified: head/tools/regression/usr.bin/jot/regress.sh
 ==============================================================================
 --- head/tools/regression/usr.bin/jot/regress.sh	Wed Jun  2 07:28:12 2010	(r208727)
 +++ head/tools/regression/usr.bin/jot/regress.sh	Wed Jun  2 07:47:29 2010	(r208728)
 @@ -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')
 
 Added: head/tools/regression/usr.bin/jot/regress.stutter2.out
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/regression/usr.bin/jot/regress.stutter2.out	Wed Jun  2 07:47:29 2010	(r208728)
 @@ -0,0 +1,20 @@
 +9
 +9
 +8
 +8
 +7
 +7
 +6
 +6
 +5
 +5
 +4
 +4
 +3
 +3
 +2
 +2
 +1
 +1
 +0
 +0
 
 Modified: head/usr.bin/jot/jot.1
 ==============================================================================
 --- head/usr.bin/jot/jot.1	Wed Jun  2 07:28:12 2010	(r208727)
 +++ head/usr.bin/jot/jot.1	Wed Jun  2 07:47:29 2010	(r208728)
 @@ -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
 
 Modified: head/usr.bin/jot/jot.c
 ==============================================================================
 --- head/usr.bin/jot/jot.c	Wed Jun  2 07:28:12 2010	(r208727)
 +++ head/usr.bin/jot/jot.c	Wed Jun  2 07:47:29 2010	(r208728)
 @@ -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;
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/123635: commit references a PR
Date: Fri, 18 Jun 2010 07:19:49 +0000 (UTC)

 Author: brian
 Date: Fri Jun 18 07:19:30 2010
 New Revision: 209284
 URL: http://svn.freebsd.org/changeset/base/209284
 
 Log:
   MFC r208728 - Fix stuttering sequences and reverse ranges
   
   PR:             123635
   Submitted by:   Ulrich Spörlein, uqs at spoerlein dot net
 
 Modified:
   stable/8/usr.bin/jot/jot.1
   stable/8/usr.bin/jot/jot.c
 Directory Properties:
   stable/8/usr.bin/jot/   (props changed)
 
 Modified: stable/8/usr.bin/jot/jot.1
 ==============================================================================
 --- stable/8/usr.bin/jot/jot.1	Fri Jun 18 06:24:40 2010	(r209283)
 +++ stable/8/usr.bin/jot/jot.1	Fri Jun 18 07:19:30 2010	(r209284)
 @@ -32,7 +32,7 @@
  .\"	@(#)jot.1	8.1 (Berkeley) 6/6/93
  .\" $FreeBSD$
  .\"
 -.Dd November 6, 2006
 +.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
 
 Modified: stable/8/usr.bin/jot/jot.c
 ==============================================================================
 --- stable/8/usr.bin/jot/jot.c	Fri Jun 18 06:24:40 2010	(r209283)
 +++ stable/8/usr.bin/jot/jot.c	Fri Jun 18 07:19:30 2010	(r209284)
 @@ -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;
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: brian 
State-Changed-When: Fri Jun 18 07:20:04 UTC 2010 
State-Changed-Why:  
Merged to stable/8, r209284 

http://www.freebsd.org/cgi/query-pr.cgi?pr=123635 
>Unformatted:
