当我使用qsort for double时的问题

时间:2013-10-08 04:10:41

标签: c qsort

我的英语很差,所以如果有任何错误,请原谅我。谢谢!

当我使用qsort对此结构进行排序时,我遇到了这个问题:

    typedef struct 
{
    double cost,earn;
}ac;

我想按照这样排序:

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

但它不起作用。当我改变这个时,它起作用了:

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

为什么会发生这种情况?两种功能有什么不同吗?或者代码的其他部分可能是错误的?

3 个答案:

答案 0 :(得分:1)

compare函数必须返回一个小于零的整数,等于零或大于零,具体取决于您希望这两个项目的排序方式。

在第一个示例中,您返回>的结果操作。这是0或1。

答案 1 :(得分:1)

您可以很容易地看到自己,这两个功能之间存在差异。第一个在> 0.0语句的表达式的末尾包含return。 (另外,第一个使用除法,而第二个使用乘法。但是,如果值是非负的,则应用于公式的转换实际上执行等效比较而不会遭受除零的危险。)

请注意,两种实现都不是很好。正如您已经注意到的那样,第一个甚至不会远程执行qsort的三态比较功能。只要double值相对较小,第二个就可以正常工作。但随着这些值变大,从doubleint的转换可能会开始溢出,从而导致未定义的行为。

因此,不要使用直接减法来生成三态比较结果(除了,可能是小于int的类型)。如果您需要比较两个值,例如ab,请使用return (a > b) - (a < b)惯用法。这就是你的情况下的样子

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

答案 2 :(得分:0)

第一个函数只会返回0或1。

第二个函数将返回“负数”,0或“正数”,这可能是您要表示的“小于”,“相等”和“大于”