Why qsort from stdlib doesnt work with double values? [C]

6.5k views Asked by At

I wrote a simple program to sort out my array. The problem is that the code works with int values only while I need my array to have double elements ... Any help?

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

double values[] = { 88, 56, 100, 2, 25 };

int cmpfunc (const void * a, const void * b)
{
    return ( *(int*)a - *(int*)b );
}

int main()
{
    int n;

    printf("Before sorting the list is: \n");
    for( n = 0 ; n < 5; n++ )
    {
        printf("%.2f ", values[n]);
    }

    printf("\n\n");

    qsort(values, 5, sizeof(double), cmpfunc);

    printf("\nAfter sorting the list is: \n");
    for( n = 0 ; n < 5; n++ )
    {
        printf("%.2f ", values[n]);
    }

    printf("\n\n");

    return(0);
}

WORKING CODE:

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

double values[] = { 88, 56, 100, 2, 25 };

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;
}

int main()
{
    int n;

    printf("Before sorting the list is: \n");
    for( n = 0 ; n < 5; n++ )
    {
        printf("%.2f ", values[n]);
    }

    printf("\n\n");

    qsort(values, 5, sizeof(double), compare);

    printf("\nAfter sorting the list is: \n");
    for( n = 0 ; n < 5; n++ )
    {
        printf("%.2f ", values[n]);
    }

    printf("\n\n");

    return(0);
}
3

There are 3 answers

0
piokuc On BEST ANSWER

You want to sort doubles but you compare them as ints... Try this comparison function:

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

Did you miss double* conversion ?:

Also fix as one of the comment says

int cmpfunc (const void * a, const void * b)
{
  return (*(double*)a > *(double*)b) ? 1 : (*(double*)a < *(double*)b) ? -1:0 ;
}
15
ouah On

You comparison function is for int not for double:

int cmpfunc (const void * a, const void * b)
{
    return ( *(int*)a - *(int*)b );
}

Note that comparing floating point is different than comparing integer values. Because of floating point precision, it's not enough to change int * to double * above, you should use an epsilon constant for comparison.

http://c-faq.com/fp/fpequal.html

EDIT: I striked the above paragraph as it is not relevant for sorting, see the comments section. I don't delete my answer to keep the comments visible.