Question

My english is very poor,so if there is any mistake please forgive me. Thank you !

i have this problem when i using qsort to sort this struct:

    typedef struct 
{
    double cost,earn;
}ac;

i want to sort it like this:

int cmp(const void *a,const void *b)
{
    ac this_a=*(ac*)a;
    ac this_b=*(ac*)b;
    return (this_b.earn/this_b.cost-this_a.earn/this_a.cost)>0.0;
}

but it didn't work. when i changed to this,it worked:

int cmp(const void *a,const void *b)
{
    ac this_a=*(ac*)a;
    ac this_b=*(ac*)b;
    return (this_a.cost*this_b.earn-this_a.earn*this_b.cost);
}

Why this happend?IS there Any different between the two function? Or maybe the other part of the code is wrong?

Was it helpful?

Solution

The compare function must return an integer less than zero, equal to zero or greater than zero depending on how you want the two items sorted.

In your first example, you return the result of an > operation. This is 0 or 1.

OTHER TIPS

As you can easily see yourself, there is a difference between the two functions. The first one contains > 0.0 at the end in the expression in return statement. (Also, the first one uses division while the second one uses multiplication. However, if the values are non-negative, the transformation applied to the formula actually performs an equivalent comparison without suffering from the danger of division by zero.)

Note that neither implementation is good. The first one does not even remotely do what a tri-state comparison function for qsort is supposed to do, as you already noticed. The second one might work correctly as long as the double values are relatively small. But as these values get larger, the conversion from double to int might begin to overflow, causing undefined behavior.

So, don't ever use direct subtraction for generating the tri-state comparison result (except for, maybe, types smaller than int). If you need to compare two values, say, a and b, use the return (a > b) - (a < b) idiom. This is how it might look in your case

double lhs = this_a.cost * this_b.earn;
double rhs = this_a.earn * this_b.cost;
return (lhs > rhs) - (lhs < rhs);

The first function will only ever return 0 or 1.

The second function will return "negative number", 0, or "positive number" which is probably what you want to represent "less than", "equal", and "greater than"

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top