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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.