Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qsort and Comparators weird behaviour. C

So, I am using qsort in my C program from C library. It works as expected so I decided to play around with comparators.

Comparator 1 (I use this):

 int compare (const void * a, const void * b)
{
  if (*(double*)a > *(double*)b) return 1;
  else if (*(double*)a < *(double*)b) return -1;
  else return 0;  
}

Comparator 2:

int comp (const void *a, const void *b)
{
    const double *ia = (const double *)a; // casting pointer types 
    const double *ib = (const double *)b;
    return *ia  - *ib; 
}

The first one works as I want to. The second one is supposed to do the same the first one. I would like to use the second because the program runs a bit faster, but the thing it that it doesn't really sort anything!

I am pretty sure that I have used comparator #2 on smaller arrays and it worked. Unless I am missing something there.

like image 813
Mpr. Moe Avatar asked Mar 10 '23 14:03

Mpr. Moe


1 Answers

The second one is supposed to do the same the first one.

At the first glance it should, but upon closer examination it turns out that it shouldn't.

Consider, for example, comparing 5.3 and 4.9. It's clear that the first number is greater than the second one; however, subtracting one from the other produces 0.4, which rounds down to zero on conversion to int, telling qsort that 5.3 and 4.9 are equal to each other.

What you want is to apply signum function to the difference of the two arguments. Unfortunately, C standard does not define one; see this Q&A for several good work-arounds.

like image 79
Sergey Kalinichenko Avatar answered Mar 16 '23 13:03

Sergey Kalinichenko