From: Pádraig Brady
Date: Tue, 2 Sep 2025 15:35:52 +0000 (+0100) Subject: seq: be more accurate with large integer start values X-Git-Tag: v9.8~82 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=701416709dcd5f0d6853ffe86086529afbd310b7;p=thirdparty%2Fcoreutils.git 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 --- diff --git a/NEWS b/NEWS index 24430cedbe..2da3b04b9e 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 ea9b7d8a4f..59de497984 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 86f82d88bc..eaf812d3bc 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