Search code examples
csortingcomparisonfunction-definitionqsort

Why does qsort produce different output for same array but different ordering?


I am trying to sort an array in descending order with the help of qsort in C.

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

int compareFloat(const void* p1, const void* p2){
    const float* pa = p1;
    const float* pb = p2;
    return pb - pa;
}

int main()
{
    float arr[] = {1.5, 1.6, 1.38};
    qsort(arr, 3, sizeof(float), compareFloat);
    printf("%.2f %.2f %.2f", arr[0], arr[1], arr[2]);
    return 0;
}

The output for above code is "1.60 1.38 1.50", which is wrong; but, when the array is initialized as float arr[] = {1.38, 1.6, 1.5}, the answer is correct (i.e. "1.6, 1.5, 1.38").

Why?


Solution

  • The return value of your compareFloat function is wrong … for two reasons.

    First, you are subtracting pointers, rather than the values they point to – so you would need *pb - *pa.

    But, even then, your test will fail for values like 1.6 and 1.5, because the result of that subtraction will be non-zero but less than one. Thus, when converted to the int return type, the function will return 0 (signalling that the values are the same), even though they are not.

    You need to return the result of at least two comparisons:

    int compareFloat(const void* p1, const void* p2)
    {
        const float* pa = p1;
        const float* pb = p2;
        return (*pa < *pb) - (*pa > *pb);
    }