Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C qsort not working correctly

Tags:

c

qsort

I don't know what I'm doing wrong but the following code does not sort the array properly.

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

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

int main()
{
    int x[] = { -919238029,
            -889150029,
            -826670576,
            -579609061,
            -569653113,
            -305140505,
            -216823425,
            -193439331,
            -167683147,
            -49487019,
            -45223520,
            271789961,
            275570429,
            444855014,
            559132135,
            612312607,
            664554739,
            677860351,
            1005278191,
            1031629361,
            1089012280,
            1115952521,
            1521112993,
            1530518916,
            1907515865,
            1931470931,
            -1631034645,
            -1593702794,
            -1465300620,
            -1263094822
         };
    int i;

    qsort(x, 30, sizeof(int), compare);
    for(i = 0; i < 30; i ++)
        printf("%d\n", x[i]);

    return 0;
}

produces the following output:

1521112993
1530518916
1907515865
1931470931
-1631034645
-1593702794
-1465300620
-1263094822
-919238029
-889150029
-826670576
-579609061
-569653113
-305140505
-216823425
-193439331
-167683147
-49487019
-45223520
271789961
275570429
444855014
559132135
612312607
664554739
677860351
1005278191
1031629361
1089012280
1115952521

I mean, the problem /must/ be in my compare function. Anybody notice anything strange?

like image 364
Ram Avatar asked May 23 '11 22:05

Ram


People also ask

How does the qsort function work in C?

The qsort() function sorts an array of num elements, each of width bytes in size, where the first element of the array is pointed to by base. The compare pointer points to a function, which you supply, that compares two array elements and returns an integer value specifying their relationship.

What is the last argument of the qsort library function?

The qsort() function calls this function by the pointer passed in the last argument to qsort() each time it needs to compare two elements of the array. The comparison function takes as its arguments two pointers to elements of the array being sorted.

Is qsort the same as QuickSort?

No, they aren't. qsort() is a C standard library function. "Quicksort", on the other hand, is a specific sorting algorithm. It is often used as the backing algorithm of an actual implementation of qsort() .

What sort does qsort use?

As the name suggests, qsort function uses QuickSort algorithm to sort the given array, although the C standard does not require it to implement quicksort.


1 Answers

Yeah, your "comparison" overflows. :(

Reason:

When you subtract a negative number from a positive number, your result is not necessarily positive; if it can't be represented in the data type, it'll "wrap around" the other side.

Example:

If your integer can only hold from -8 to 7 (4 bits), then what happens when you compare 4 to -4?
Well, you get 8, which is 1000 in binary, which is -8. So 4 is less than -4.

Moral:

Don't do subtraction instead of comparison, even if they tell you "look how cool this is" at school!

like image 149
user541686 Avatar answered Oct 07 '22 20:10

user541686