Re: seq: fix check for rounding error/truncation
On Mon, 12 Jun 2023 18:48:56 +0100, Stuart Henderson wrote: > Neither of these are really ideal, and mean that we still need gseq > for integers >= 1,000,000 > > $ seq 99 99 > 99 > $ seq 100 100 > 1e+06 > > $ gseq 105 105 > 105 That probably requires a separate code path specifically for integers. One thing at a time. - todd
Re: seq: fix check for rounding error/truncation
On 2023/06/12 11:20, Todd C. Miller wrote: > We need to compare the printable version of the last value displayed, > not the floating point representation. Otherwise, we may print the > last value twice. > > Old: > > $ seq 105 105 > 1.05e+06 > 1.05e+06 > > New: > > $ seq 105 105 > 1.05e+06 Neither of these are really ideal, and mean that we still need gseq for integers >= 1,000,000 $ seq 99 99 99 $ seq 100 100 1e+06 $ gseq 105 105 105 > We really need seq regression tests. I have a few that I will > commit after this is in. > > - todd > > Index: usr.bin/seq/seq.c > === > RCS file: /cvs/src/usr.bin/seq/seq.c,v > retrieving revision 1.6 > diff -u -p -u -r1.6 seq.c > --- usr.bin/seq/seq.c 25 Feb 2022 16:00:39 - 1.6 > +++ usr.bin/seq/seq.c 12 Jun 2023 17:13:44 - > @@ -89,13 +89,13 @@ main(int argc, char *argv[]) > double first = 1.0; > double last = 0.0; > double incr = 0.0; > - double last_shown_value = 0.0; > + double prev = 0.0; > double cur, step; > struct lconv *locale; > char *fmt = NULL; > const char *sep = "\n"; > const char *term = "\n"; > - char *cur_print, *last_print; > + char *cur_print, *last_print, *prev_print; > char pad = ZERO; > > if (pledge("stdio", NULL) == -1) > @@ -181,29 +181,31 @@ main(int argc, char *argv[]) > if (cur != first) > fputs(sep, stdout); > printf(fmt, cur); > - last_shown_value = cur; > + prev = cur; > } > > /* >* Did we miss the last value of the range in the loop above? >* >* We might have, so check if the printable version of the last > - * computed value ('cur') and desired 'last' value are equal. If they > - * are equal after formatting truncation, but 'cur' and > - * 'last_shown_value' are not equal, it means the exit condition of the > - * loop held true due to a rounding error and we still need to print > - * 'last'. > + * computed value ('cur') and desired 'last' value are equal. If > + * they are equal after formatting truncation, but 'cur' and 'prev' > + * are different, it means the exit condition of the loop held true > + * due to a rounding error and we still need to print 'last'. >*/ > if (asprintf(&cur_print, fmt, cur) == -1 || > - asprintf(&last_print, fmt, last) == -1) > + asprintf(&last_print, fmt, last) == -1 || > + asprintf(&prev_print, fmt, prev) == -1) > err(1, "asprintf"); > - if (strcmp(cur_print, last_print) == 0 && cur != last_shown_value) { > + if (strcmp(cur_print, last_print) == 0 && > + strcmp(cur_print, prev_print) != 0) { > if (cur != first) > fputs(sep, stdout); > fputs(last_print, stdout); > } > free(cur_print); > free(last_print); > + free(prev_print); > > fputs(term, stdout); > >
Re: seq: fix check for rounding error/truncation
For context, see: https://chaos.social/@Gottox/110527807405964874 https://github.com/chimera-linux/chimerautils/commit/1ecc1e99d4a309631e846a868b5a422f996704ac
seq: fix check for rounding error/truncation
We need to compare the printable version of the last value displayed, not the floating point representation. Otherwise, we may print the last value twice. Old: $ seq 105 105 1.05e+06 1.05e+06 New: $ seq 105 105 1.05e+06 We really need seq regression tests. I have a few that I will commit after this is in. - todd Index: usr.bin/seq/seq.c === RCS file: /cvs/src/usr.bin/seq/seq.c,v retrieving revision 1.6 diff -u -p -u -r1.6 seq.c --- usr.bin/seq/seq.c 25 Feb 2022 16:00:39 - 1.6 +++ usr.bin/seq/seq.c 12 Jun 2023 17:13:44 - @@ -89,13 +89,13 @@ main(int argc, char *argv[]) double first = 1.0; double last = 0.0; double incr = 0.0; - double last_shown_value = 0.0; + double prev = 0.0; double cur, step; struct lconv *locale; char *fmt = NULL; const char *sep = "\n"; const char *term = "\n"; - char *cur_print, *last_print; + char *cur_print, *last_print, *prev_print; char pad = ZERO; if (pledge("stdio", NULL) == -1) @@ -181,29 +181,31 @@ main(int argc, char *argv[]) if (cur != first) fputs(sep, stdout); printf(fmt, cur); - last_shown_value = cur; + prev = cur; } /* * Did we miss the last value of the range in the loop above? * * We might have, so check if the printable version of the last -* computed value ('cur') and desired 'last' value are equal. If they -* are equal after formatting truncation, but 'cur' and -* 'last_shown_value' are not equal, it means the exit condition of the -* loop held true due to a rounding error and we still need to print -* 'last'. +* computed value ('cur') and desired 'last' value are equal. If +* they are equal after formatting truncation, but 'cur' and 'prev' +* are different, it means the exit condition of the loop held true +* due to a rounding error and we still need to print 'last'. */ if (asprintf(&cur_print, fmt, cur) == -1 || - asprintf(&last_print, fmt, last) == -1) + asprintf(&last_print, fmt, last) == -1 || + asprintf(&prev_print, fmt, prev) == -1) err(1, "asprintf"); - if (strcmp(cur_print, last_print) == 0 && cur != last_shown_value) { + if (strcmp(cur_print, last_print) == 0 && + strcmp(cur_print, prev_print) != 0) { if (cur != first) fputs(sep, stdout); fputs(last_print, stdout); } free(cur_print); free(last_print); + free(prev_print); fputs(term, stdout);