aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPádraig Brady <P@draigBrady.com>2025-09-02 16:35:52 +0100
committerPádraig Brady <P@draigBrady.com>2025-09-02 20:51:55 +0100
commit701416709dcd5f0d6853ffe86086529afbd310b7 (patch)
tree99c84fbce0afb51e58de01ad2fed83c8044432a3
parentdf: pacify static analysis (diff)
downloadcoreutils-701416709dcd5f0d6853ffe86086529afbd310b7.tar.gz
coreutils-701416709dcd5f0d6853ffe86086529afbd310b7.zip
seq: be more accurate with large integer start values
* src/seq.c (main): Avoid possibly innacurate conversion to long double, for all digit start values. * tests/seq/seq-long-double.sh: Add a test case. * NEWS: Mention the improvement. Fixes https://bugs.gnu.org/79369
-rw-r--r--NEWS6
-rw-r--r--src/seq.c8
-rwxr-xr-xtests/seq/seq-long-double.sh9
3 files changed, 19 insertions, 4 deletions
diff --git a/NEWS b/NEWS
index 24430cedb..2da3b04b9 100644
--- a/NEWS
+++ b/NEWS
@@ -112,11 +112,15 @@ GNU coreutils NEWS -*- outline -*-
tsort now accepts and ignores -w.
-** Performance improvements
+** Improvements
'factor' is now much faster at identifying large prime numbers,
and significantly faster on composite numbers greater than 2^128.
+ 'seq' is more accurate with large integer start values.
+ Previously 'seq 18446744073709551617 inf | head -n1' would
+ output the number before the user specified start value.
+
** Build-related
cksum was not compilable by Apple LLVM 10.0.0 x86-64, which
diff --git a/src/seq.c b/src/seq.c
index ea9b7d8a4..59de49798 100644
--- a/src/seq.c
+++ b/src/seq.c
@@ -628,6 +628,8 @@ main (int argc, char **argv)
usage (EXIT_FAILURE);
}
+ char const *user_start = n_args == 1 ? "1" : argv[optind];
+
/* If the following hold:
- no format string, [FIXME: relax this, eventually]
- integer start (or no start)
@@ -648,7 +650,7 @@ main (int argc, char **argv)
&& all_digits_p (argv[optind + 2])))
&& !equal_width && !format_str && strlen (separator) == 1)
{
- char const *s1 = n_args == 1 ? "1" : argv[optind];
+ char const *s1 = user_start;
char const *s2 = argv[optind + (n_args - 1)];
seq_fast (s1, s2, step.value);
}
@@ -683,7 +685,9 @@ main (int argc, char **argv)
{
char *s1;
char *s2;
- if (asprintf (&s1, "%0.Lf", first.value) < 0)
+ if (all_digits_p (user_start))
+ s1 = xstrdup (user_start);
+ else if (asprintf (&s1, "%0.Lf", first.value) < 0)
xalloc_die ();
if (! isfinite (last.value))
s2 = xstrdup ("inf"); /* Ensure "inf" is used. */
diff --git a/tests/seq/seq-long-double.sh b/tests/seq/seq-long-double.sh
index 86f82d88b..eaf812d3b 100755
--- a/tests/seq/seq-long-double.sh
+++ b/tests/seq/seq-long-double.sh
@@ -40,7 +40,14 @@ a=$INTMAX_MAX
b=$INTMAX_OFLOW
seq $a $b > out || fail=1
-printf "$a\n$b\n" > exp || fail=1
+printf "$a\n$b\n" > exp || framework_failure_
+compare exp out || fail=1
+
+# Test case fixed in v9.8
+# I.e. All digit start, with non digits end
+a=18446744073709551617
+seq $a inf | head -n1 > out || fail=1
+printf "$a\n" > exp || framework_failure_
compare exp out || fail=1
Exit $fail