问题试图使用C qsort函数

问题试图使用C qsort函数

问题描述:

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

float values[] = { 4, 1, 10, 9, 2, 5, -1, -9, -2,10000,-0.05,-3,-1.1 };

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

int main ()
{

    int i;

    qsort (values, 13, sizeof(float), compare);

    for (i = 0; i < 13; i++)
    {
        printf ("%f ",values[ i ]);
    }
    putchar('\n');

    return 0;
}

的结果是:

-9.000000 -3.000000 -2.000000 -1.000000 -1.100000 -0.050000 1.000000 2.000000 4.000000 5.000000 9.000000 10.000000 10000.000000

-9.000000 -3.000000 -2.000000 -1.000000 -1.100000 -0.050000 1.000000 2.000000 4.000000 5.000000 9.000000 10.000000 10000.000000

由于-1和-1.1的顺序改变这是错误的。
我相信,它正在发生,因为我的比较功能。

It's wrong because the order of -1 and -1.1 is changed. I believe it is happening because my "compare" function.

我该如何解决这个问题?

How can I fix this?

感谢

您比较函数被打破了。它说,例如, -1.0 等于(相当于)为 -1.1 ,因为(INT)((-1.0) - (-1.1))是零。换句话说,你自己告诉的qsort 的相对顺序 -1.0 -1.1 无所谓。你为什么感到惊讶,在最终订购这些值进行排序?

Your comparison function is broken. It says, for example, that -1.0 is equal (equivalent) to -1.1, since (int) ((-1.0) - (-1.1)) is zero. In other words, you yourself told qsort that the relative order of -1.0 and -1.1 does not matter. Why are you surprised that in the resultant ordering these values are not sorted?

在一般情况下,你应该避免减去从另一个比较数值。这是行不通的。对于浮点类型它可能会产生了好几个不同的原因,其中之一的你只看到自己的IM precise结果。对于整数类型可能溢出。

In general, you should avoid comparing numerical values by subtracting one from another. It just doesn't work. For floating-point types it might produce imprecise results for quite a few different reasons, one of which you just observed yourself. For integer types it might overflow.

通用成语比较两个数值 A B 的qsort 看起来(A&GT; b) - (A&LT; b)。记住它并使用它。你的情况,这将是

The generic idiom for comparing two numerical values a and b for qsort looks as (a > b) - (a < b). Remember it and use it. In your case that would be

int compare (const void * a, const void * b)
{
  float fa = *(const float*) a;
  float fb = *(const float*) b;
  return (fa > fb) - (fa < fb);
}

在C code那么它可能使绝对意义上定义一个宏

In C code it might make perfect sense to define a macro

#define COMPARE(a, b) (((a) > (b)) - ((a) < (b)))

和使用它来代替明确地阐明了比较。

and use it instead of spelling out the comparisons explicitly.