Module Name:    src
Committed By:   mlelstv
Date:           Sat Feb 24 10:10:05 UTC 2024

Modified Files:
        src/usr.bin/seq: seq.c

Log Message:
Chose better number format.


To generate a diff of this commit:
cvs rdiff -u -r1.12 -r1.13 src/usr.bin/seq/seq.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/seq/seq.c
diff -u src/usr.bin/seq/seq.c:1.12 src/usr.bin/seq/seq.c:1.13
--- src/usr.bin/seq/seq.c:1.12	Sat Mar 20 22:10:17 2021
+++ src/usr.bin/seq/seq.c	Sat Feb 24 10:10:04 2024
@@ -31,7 +31,7 @@
 #ifndef lint
 __COPYRIGHT("@(#) Copyright (c) 2005\
  The NetBSD Foundation, Inc.  All rights reserved.");
-__RCSID("$NetBSD: seq.c,v 1.12 2021/03/20 22:10:17 cheusov Exp $");
+__RCSID("$NetBSD: seq.c,v 1.13 2024/02/24 10:10:04 mlelstv Exp $");
 #endif /* not lint */
 
 #include <ctype.h>
@@ -56,6 +56,8 @@ __RCSID("$NetBSD: seq.c,v 1.12 2021/03/2
 
 const char *decimal_point = ".";	/* default */
 char default_format[] = { "%g" };	/* default */
+char default_format_fmt[] = { "%%.%uf" };
+#define MAXPRECISION 40
 
 /* Prototypes */
 
@@ -65,9 +67,29 @@ int decimal_places(const char *);
 int numeric(const char *);
 int valid_format(const char *);
 
-char *generate_format(double, double, double, int, char);
+unsigned get_precision(const char *, unsigned);
+char *generate_format(double, double, double, int, char, char *);
 char *unescape(char *);
 
+unsigned
+get_precision(const char *number, unsigned minprec)
+{
+	const char *p;
+	unsigned prec;
+
+	p = strstr(number, decimal_point);
+	if (p) {
+		prec = strlen(number) - (p - number);
+		if (prec > 0)
+			prec -= 1;
+		if (prec > MAXPRECISION)
+			prec = MAXPRECISION;
+	} else
+		prec = 0;
+
+	return prec < minprec ? minprec : prec;
+}
+
 /*
  * The seq command will print out a numeric sequence from 1, the default,
  * to a user specified upper limit by 1.  The lower bound and increment
@@ -79,6 +101,7 @@ main(int argc, char *argv[])
 {
 	int c = 0, errflg = 0;
 	int equalize = 0;
+	unsigned prec;
 	double first = 1.0;
 	double last = 0.0;
 	double incr = 0.0;
@@ -87,6 +110,8 @@ main(int argc, char *argv[])
 	const char *sep = "\n";
 	const char *term = "\n";
 	char pad = ZERO;
+	char buf[6]; /* %.MAXPRECISIONf */
+
 
 	/* Determine the locale's decimal point. */
 	locale = localeconv();
@@ -136,12 +161,16 @@ main(int argc, char *argv[])
 	}
 
 	last = e_atof(argv[argc - 1]);
+	prec = get_precision(argv[argc - 1], 0);
 
-	if (argc > 1)
+	if (argc > 1) {
 		first = e_atof(argv[0]);
+		prec = get_precision(argv[0], prec);
+	}
 	
 	if (argc > 2) {
 		incr = e_atof(argv[1]);
+		prec = get_precision(argv[1], prec);
 		/* Plan 9/GNU don't do zero */
 		if (incr == 0.0)
 			errx(1, "zero %screment", (first < last)? "in" : "de");
@@ -167,8 +196,15 @@ main(int argc, char *argv[])
 	         * XXX to be bug for bug compatible with Plan 9 add a
 		 * newline if none found at the end of the format string.
 		 */
-	} else
-		fmt = generate_format(first, incr, last, equalize, pad);
+	} else {
+		if (prec == 0)
+			fmt = default_format;
+		else {
+			sprintf(buf, default_format_fmt, prec);
+			fmt = buf;
+		}
+		fmt = generate_format(first, incr, last, equalize, pad, fmt);
+	}
 
 	if (incr > 0) {
 		printf(fmt, first);
@@ -428,14 +464,15 @@ decimal_places(const char *number)
  * when "%g" prints as "%e" (this way no width adjustments are made)
  */
 char *
-generate_format(double first, double incr, double last, int equalize, char pad)
+generate_format(double first, double incr, double last,
+    int equalize, char pad, char *deffmt)
 {
 	static char buf[256];
 	char cc = '\0';
 	int precision, width1, width2, places;
 
 	if (equalize == 0)
-		return (default_format);
+		return deffmt;
 
 	/* figure out "last" value printed */
 	if (first > last)
@@ -443,12 +480,12 @@ generate_format(double first, double inc
 	else
 		last = first + incr * floor((last - first) / incr);
 
-	sprintf(buf, "%g", incr);
+	sprintf(buf, deffmt, incr);
 	if (strchr(buf, 'e'))
 		cc = 'e';
 	precision = decimal_places(buf);
 
-	width1 = sprintf(buf, "%g", first);
+	width1 = sprintf(buf, deffmt, first);
 	if (strchr(buf, 'e'))
 		cc = 'e';
 	if ((places = decimal_places(buf)))
@@ -456,7 +493,7 @@ generate_format(double first, double inc
 
 	precision = MAX(places, precision);
 
-	width2 = sprintf(buf, "%g", last);
+	width2 = sprintf(buf, deffmt, last);
 	if (strchr(buf, 'e'))
 		cc = 'e';
 	if ((places = decimal_places(buf)))

Reply via email to