Q:

Why are my qsort results incorrect?

When I run add cards using add_card, on the 7th card it is supposed to sort all of the cards.  But when I run this I get a semi-ordered result. 
>> require 'ext/straight_count' #=> true                                                                                          >> s = EV::StraightCount.new; s.add_card(5,0); s.add_card(8,1); s.add_card(12,2); s.add_card(14,3); s.add_card(12,4); s.add_card(3,5); s.add_card(5,6)
card: 12
card: 5
card: 12
card: 14
card: 8
card: 5
card: 3

I don't think there is a problem with NUM2INT, because when I print the array back unordered, it comes out as expected. 
straight.h
int *pCards, *pSortedCards;
int cCards[NUM_CARDS], cSortedCards[NUM_CARDS];

straight.c
void Init_straight() 
{
    pCards = &cCards[0];
}

static VALUE 
add_card(VALUE self, int rCardValue, int rCardIndex)  
{
    *(pCards + NUM2INT(rCardIndex)) = NUM2INT(rCardValue);
    if (NUM2INT(rCardIndex) == 6)
        check_for_straight();

    return Qnil;
}

check_for_straight()
{
    sort_by_value(pCards);
}

card_sort.c
int compare_card_values (const void *a, const void *b) 
{
    const double *da = (const double *) a;
    const double *db = (const double *) b;
    return (*da > *db) - (*da < *db);
}

void sort_by_value(int *pCards) 
{
    qsort(pCards, NUM_CARDS, sizeof(pCards[0]), compare_card_values);
}

A:

You're casting the card values to double in compare_card_values even though the array contains int. Try this instead:
int compare_card_values (const void *a, const void *b) 
{
    const int *da = (const int *) a;
    const int *db = (const int *) b;
    return (*da > *db) - (*da < *db);
}

