bug#78985: sort-float failure on ppc64, LDBL_MIN fraction part too long for test command to parse
Pádraig Brady <[email protected]>
| Newsgroups | gmane.comp.gnu.core-utils.bugs |
|---|---|
| Message-ID | <[email protected]> |
On 12/07/2025 04:59, Collin Funk wrote: > Collin Funk <[email protected]> writes: > >>> Oh, right. Thanks. I installed the attached further patch to fix that. >>> This is cleaner anyway. >> >> This test still fails on cfarm110 for me, logs attached. >> >> I was looking at it the other day, but was unable to get a working >> version. >> >> I'll see if I have any ideas later. > > I think I see the issue now. Using this test program: > > $ cat main.c > #include <stdio.h> > int > main (void) > { > long double a = 2.225073858507201383090232717332e-308; > long double b = 2.2250738585072014e-308; > printf ("a < b: %d\n", a < b); > printf ("a > b: %d\n", a > b); > printf ("a == b: %d\n", a == b); > return 0; > } > $ gcc main.c > $ ./a.out > a < b: 0 > a > b: 0 > a == b: 1 > > And then in gdb we can see strtold returns equal numbers: > > Breakpoint 1, general_numcompare (sa=0x10051460 "2.225073858507201383090232717332e-308", sb=0x10051486 "2.2250738585072014e-308") at src/sort.c:2032 > 2032 long double a = strtold (sa, &ea); > Missing separate debuginfos, use: debuginfo-install glibc-2.17-326.el7_9.3.ppc64 > (gdb) n > 2033 long double b = strtold (sb, &eb); > (gdb) n > 2036 if (sa == ea) > (gdb) print a > $1 = 2.2250738585072013830902327173324041e-308 > (gdb) print b > $2 = 2.2250738585072013830902327173324041e-308 > (gdb) print a == b > $3 = 1 > > Maybe a solution would be to compare the strings instead of calling > strold? I guess that would make life harder though... > > Collin > > > I wonder could you break ties with string compares? I've not thought about edge cases, but something like this? diff --git a/src/sort.c b/src/sort.c index 4a1fdfd37..faeeef273 100644 --- a/src/sort.c +++ b/src/sort.c @@ -2043,7 +2043,7 @@ general_numcompare (char const *sa, char const *sb) bit-pattern, for lack of a more portable alternative. */ return (a < b ? -1 : a > b ? 1 - : a == b ? 0 + : a == b ? numcompare (sa, sb) : b == b ? -1 : a == a ? 1 : nan_compare (a, b)); Given floating point comparison is already slow, and this would only be in the equal case, perf-wise it might be ok? Testing that directly gives: $ eval $(src/getlimits) $ LDBL_ABOVE_MIN=$(echo $LDBL_MIN | sed 's/e/1e/') $ printf '%s\n' $LDBL_ABOVE_MIN $LDBL_MIN | src/sort -g 3.3621031431120935063e-4932 3.36210314311209350631e-4932 $ printf '%s\n' $LDBL_ABOVE_MIN $LDBL_MIN | /usr/bin/sort -g 3.36210314311209350631e-4932 3.3621031431120935063e-4932 cheers, Pádraig