2

I'm trying to sort an array of type double in C but I am not getting the expected output. It appears to be sorting the memory addresses instead of the actual values. I have tried changing the vairables to (*grade[i]) but then I get a "invalid type argument of unary *" error. Here is the snipit of code in question.

void sortGrade(double grade[], int n){
int i, j, swapped;
double temp;
for (i = 0; i < n; ++i)
{
    for (j = i + 1; j < n; ++j)
    {
        if (grade[i] < grade[j])
        {
            temp = grade[i];
            grade[i] = grade[j];
            grade[j] = temp;
        }//end if
    }//end inner for
}//end outer for
printf("After sort:\nGrade\n");
for (i = 0; i < n; ++i)
{
    printf("%d\n", grade[i]);
}//end for
}//end sortGrade

Any help would be greatly appreciated. Full disclosure, this is for school, but the assignment has already been submitted, now I'm just trying to figure out how to actually make it work.

6
  • 12
    Your sorting algorithm is okay. The error is when you print: Use %f or %g to print floating-point numbers. Commented Apr 29, 2016 at 14:18
  • 1
    Hard to say if you don't tell us what the expected output is. Obviously you should turn warnings on in your compiler, so M Oehms advice wouldn't be needed. With that fixed, it will be sorted, but maybe not the way you expect it. Commented Apr 29, 2016 at 14:22
  • And if you sorted memory addresses, then obviously the order of items wouldn't change. Array elements are always sorted by memory address. Commented Apr 29, 2016 at 14:23
  • M Oehm - That was all it was. Everything works as it should now. Wow do I feel like an idiot... Thanks for the help! Commented Apr 29, 2016 at 14:24
  • 5
    Don't go into the weekend feeling like an idiot, but do activate warnings next time. :) Commented Apr 29, 2016 at 14:26

3 Answers 3

4

As mentioned by @M Oehm already, you have to use %f instead of %g when printing double values. Therefore do

printf("%f\n", grade[i]);

instead of

printf("%d\n", grade[i]);

I assume that the goal was writing a sorting algorithm by hand. If not, you might want to take a look at qsort provided by stdlib. This function performs the quicksort sorting algorithm.

// qsort(array pointer, number of elements, size of one element, compare function);
qsort(grade, n, sizeof(double), compare);

In order to compare the elements you also need a compare function.

// the compare function for double values
static int compare (const void * a, const void * b)
{
  if (*(double*)a > *(double*)b) return 1;
  else if (*(double*)a < *(double*)b) return -1;
  else return 0;  
}
Sign up to request clarification or add additional context in comments.

Comments

1

You have to be careful when dealing with float and double. They are not 100% precise. Your sorting algorithm will break when dealing with numbers that seem the same but their smaller bits differ, since floats are just an approximation of real numbers.

If you want to compare two double variables, use this.

int areDoubleEqual(double a, double b) {
  if (fabs(a - b) <= 1000 * DBL_EPSILON * fabs(a + b)) {
      /*A and B are equal*/
      return 1;
  }
  return 0;
}

If you want to implement sorting, I would recommend using qsort. This is quick a example

#include <stdio.h>
#include <float.h>
#include <math.h>

int areDoubleEqual(double a, double b) {
    if (fabs(a - b) <= 1000 * DBL_EPSILON * fabs(a + b)) {
        /*A and B are equal*/
        return 1;
    }
    return 0;
}
/*This will sort in descending order. If you want ascending order, interchange 1 and -1*/
int compareDoubles(const void *a, const void *b) {
    double doubleA = *(double *) a;
    double doubleB = *(double *) b;
    if(areDoubleEqual(doubleA, doubleB)) {
        /*When A and B are equal, quick sort expects 0.
        For further details check documentation*/
        return 0;
    }
    /*A is bigger*/
    if((doubleA - doubleB) >
        ((fabs(doubleA) < fabs(doubleB) ? fabs(doubleB) :
        fabs(doubleA)) * DBL_EPSILON * 1000)) {
        return -1;
    }
    /*B is bigger*/
    return 1;
}

int main(void) {

    double doubles[5] = {4.3, 2.1, 10.564, 350332.323, 0.3};
    qsort(doubles, 5, sizeof(double), compareDoubles);
    for(int i = 0; i < 5; i++) {
        printf("%f ", doubles[i]);
    }
    printf("\n");

    return 0;
}

Comments

0

This should work:

   int i, j, swapped;
    double temp;
    for (i = 0; i < n; ++i)
    {
        for (j = i + 1; j < n; ++j)
        {
            if (grade[i] < grade[j])
            {
                temp = grade[i];
                grade[i] = grade[j];
                grade[j] = temp;
            }//end if
        }//end inner for
    }//end outer for
    printf("After sort:\nGrade\n");
    for (i = 0; i < n; ++i)
    {
        printf("%f\n", grade[i]);
    }//end for
    }//end sortGrade

The algorithm works. The only error was the printf:

printf("%f\n", grade[i]); //for double values

or better

printf("%lf\n", grade[i]); //for double values

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.