Ваша функция сравнения не работает.Он говорит, например, что -1.0
равно (эквивалентно) -1.1
, поскольку (int) ((-1.0) - (-1.1))
равно нулю.Другими словами, вы сами сказали qsort
, что относительный порядок -1.0
и -1.1
не имеет значения.Почему вы удивляетесь, что в результирующем порядке эти значения не сортируются?
В общем, вам следует избегать сравнения числовых значений путем вычитания одного из другого.Это просто не работает.Для типов с плавающей запятой это может привести к неточным результатам по нескольким причинам, одна из которых вы только что наблюдали сами.Для целочисленных типов он может быть переполнен.
Общая идиома для сравнения двух числовых значений a
и b
для qsort
выглядит как (a > b) - (a < b)
.Помните это и используйте это.В вашем случае это будет
int compare (const void * a, const void * b)
{
float fa = *(const float*) a;
float fb = *(const float*) b;
return (fa > fb) - (fa < fb);
}
. В коде на С может иметь смысл определить макрос
#define COMPARE(a, b) (((a) > (b)) - ((a) < (b)))
и использовать его вместо того, чтобы явно описывать сравнения.