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?
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.
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);
}
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.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…