Search code examples
cqsort

Using qsort() to sort doubles in an array of structs


I am using qsort() to sort double values in an array of structs in descending order. I have the following code:

#include <stdio.h>
#include <stdlib.h>

typedef struct page {
   double val;
   int id;
} page;

int cmpfunc(const void *a, const void *b) {
  const page *pageA = (page*)a;
  const page *pageB = (page*)b;
  return -(pageA->val - pageB->val);
}

int main(void) {
  page array[5];
  int n;
  int i = 1;

for(n = 0; n < 5; n++) {
    array[n].id = i;
    i++;
}

array[0].val = 0.0608;
array[1].val = 0.2230; 
array[2].val = 0.1673;
array[3].val = 0.1442;
array[4].val = 0.2499;

printf("Before sorting\n");

for(n = 0; n < 5; n++) {
    printf("page id = %d, val = %lf \n", array[n].id, array[n].val);
}

qsort(array, 5, sizeof(page), cmpfunc);

printf("\nAfter sorting\n");

for(n = 0; n < 5; n++) {
    printf("page id = %d, val = %lf \n", array[n].id, array[n].val);
}

return 0;
}

I have tried using qsort() to sort integers and it has worked. However, when trying to sort doubles, my output is not sorted:

After sorting:

page id = 2, val = 0.223000

page id = 3, val = 0.167300

page id = 4, val = 0.144200

page id = 5, val = 0.249900

page id = 1, val = 0.060800

I am not sure why the output is not sorted properly. I have read posts online about sorting values in an array of structs and I believe that my comparison function is correct. Any insights would be really appreciated.


Solution

  • It is because the compare function returns an integer. The result of -(pageA->val - pageB->val) will get rounded.

    Switch to

    if (pageA->val == pageB->val)
        return 0;
    else if(pageA->val > pageB->val)
        return 1;
    else
        return -1;
    

    I believe that my comparison function is correct.

    Protip here. If you only believe that a function is correct, then test it to make sure. You verified that the sorting does not work by printing the result. You could also have printed the outputs for the compare function.