Writing a compare function for a structure for qsort?












2















I'm having trouble writing a compare function for qsort function in C. This is what I currently have:



int cmpfunc(const void *a, const void *b) {
return (*(Individual*)a->fitness - *(Individual*)b->fitness);
}


I know how the compare function works but I don't understand how to reference an integer value within my structure called Individual. Here is the structure of the Individual.



typedef struct {
PPM_IMAGE image;
double fitness;
} Individual;


I want to compare the fitness values within the structure.










share|improve this question

























  • @kiner_shah Though the linked compare is correct for some types of floating point compare, it doesn't apply here.

    – 4386427
    Nov 25 '18 at 11:27






  • 1





    @kiner_shah You provided a link to a compare function which isn't relevant for this question

    – 4386427
    Nov 25 '18 at 17:06
















2















I'm having trouble writing a compare function for qsort function in C. This is what I currently have:



int cmpfunc(const void *a, const void *b) {
return (*(Individual*)a->fitness - *(Individual*)b->fitness);
}


I know how the compare function works but I don't understand how to reference an integer value within my structure called Individual. Here is the structure of the Individual.



typedef struct {
PPM_IMAGE image;
double fitness;
} Individual;


I want to compare the fitness values within the structure.










share|improve this question

























  • @kiner_shah Though the linked compare is correct for some types of floating point compare, it doesn't apply here.

    – 4386427
    Nov 25 '18 at 11:27






  • 1





    @kiner_shah You provided a link to a compare function which isn't relevant for this question

    – 4386427
    Nov 25 '18 at 17:06














2












2








2








I'm having trouble writing a compare function for qsort function in C. This is what I currently have:



int cmpfunc(const void *a, const void *b) {
return (*(Individual*)a->fitness - *(Individual*)b->fitness);
}


I know how the compare function works but I don't understand how to reference an integer value within my structure called Individual. Here is the structure of the Individual.



typedef struct {
PPM_IMAGE image;
double fitness;
} Individual;


I want to compare the fitness values within the structure.










share|improve this question
















I'm having trouble writing a compare function for qsort function in C. This is what I currently have:



int cmpfunc(const void *a, const void *b) {
return (*(Individual*)a->fitness - *(Individual*)b->fitness);
}


I know how the compare function works but I don't understand how to reference an integer value within my structure called Individual. Here is the structure of the Individual.



typedef struct {
PPM_IMAGE image;
double fitness;
} Individual;


I want to compare the fitness values within the structure.







c genetic-algorithm qsort






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 25 '18 at 9:22









chqrlie

61.2k747104




61.2k747104










asked Nov 25 '18 at 6:18









Akila KavisingheAkila Kavisinghe

133




133













  • @kiner_shah Though the linked compare is correct for some types of floating point compare, it doesn't apply here.

    – 4386427
    Nov 25 '18 at 11:27






  • 1





    @kiner_shah You provided a link to a compare function which isn't relevant for this question

    – 4386427
    Nov 25 '18 at 17:06



















  • @kiner_shah Though the linked compare is correct for some types of floating point compare, it doesn't apply here.

    – 4386427
    Nov 25 '18 at 11:27






  • 1





    @kiner_shah You provided a link to a compare function which isn't relevant for this question

    – 4386427
    Nov 25 '18 at 17:06

















@kiner_shah Though the linked compare is correct for some types of floating point compare, it doesn't apply here.

– 4386427
Nov 25 '18 at 11:27





@kiner_shah Though the linked compare is correct for some types of floating point compare, it doesn't apply here.

– 4386427
Nov 25 '18 at 11:27




1




1





@kiner_shah You provided a link to a compare function which isn't relevant for this question

– 4386427
Nov 25 '18 at 17:06





@kiner_shah You provided a link to a compare function which isn't relevant for this question

– 4386427
Nov 25 '18 at 17:06












2 Answers
2






active

oldest

votes


















5














This part



*(Individual*)a->fitness


is wrong. You try to access fitness using -> but at the same time you dereference the pointer using *. You can't do both!



Here are two solutions.



Solution A: Dereference using * and access fitness using .



(*(Individual*)a).fitness


Solution B: Access fitness using ->



((Individual*)a)->fitness


Both solutions also requires a cast from void* to Individual*.



The same apply for variable b



If you are a beginner in C I'll recommend that you avoid using compact statements where multiple things happens. Instead split the compact statement into a number of individual statements. That will make the code easier to understand and debug. Like:



int cmpfunc (const void * a, const void * b){
Individual* pA = a;
Individual* pB = b;
double fitnessA = pA->fitness;
double fitnessB = pB->fitness;
return fitnessA - fitnessB;
}


You don't need to worry about performance. The compiler will optimize the code to be just as efficient as the single statement code.



That said - as spotted by @chqrlie - notice that the compare code is wrong!



The function returns an integer but fitnessA - fitnessB is a double that will be converted to an integer. So 0.1 - 0.0 will end up returning 0 - which is not what you want.



You can see this answer https://stackoverflow.com/a/53466034/4386427 from @chqrlie for further details.



The code can also be changed like:



int cmpfunc (const void * a, const void * b){
Individual* pA = a;
Individual* pB = b;
double fitnessA = pA->fitness;
double fitnessB = pB->fitness;
if (fitnessA > fitnessB) return 1;
if (fitnessA < fitnessB) return -1;
return 0;
}





share|improve this answer

































    2














    Assuming you call qsort with an array of Individual structures, you should cast the arguments received by the compare function as pointers to Individual structures, preferably const Individual * to avoid warnings.



    You can then compare the fitness members and return an ordering value. Note that you cannot just return the difference of the values as these may be non integral and the difference may even overflow the range of type int.



    Here is a classic way to do this:



    int cmpfunc(const void *a, const void *b) {
    const Individual *aa = a;
    const Individual *bb = b;
    /* return -1, 0 or 1 depending on the comparison results */
    return (aa->fitness > bb->fitness) - (aa->fitness < bb->fitness);
    }





    share|improve this answer

























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53465147%2fwriting-a-compare-function-for-a-structure-for-qsort%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      5














      This part



      *(Individual*)a->fitness


      is wrong. You try to access fitness using -> but at the same time you dereference the pointer using *. You can't do both!



      Here are two solutions.



      Solution A: Dereference using * and access fitness using .



      (*(Individual*)a).fitness


      Solution B: Access fitness using ->



      ((Individual*)a)->fitness


      Both solutions also requires a cast from void* to Individual*.



      The same apply for variable b



      If you are a beginner in C I'll recommend that you avoid using compact statements where multiple things happens. Instead split the compact statement into a number of individual statements. That will make the code easier to understand and debug. Like:



      int cmpfunc (const void * a, const void * b){
      Individual* pA = a;
      Individual* pB = b;
      double fitnessA = pA->fitness;
      double fitnessB = pB->fitness;
      return fitnessA - fitnessB;
      }


      You don't need to worry about performance. The compiler will optimize the code to be just as efficient as the single statement code.



      That said - as spotted by @chqrlie - notice that the compare code is wrong!



      The function returns an integer but fitnessA - fitnessB is a double that will be converted to an integer. So 0.1 - 0.0 will end up returning 0 - which is not what you want.



      You can see this answer https://stackoverflow.com/a/53466034/4386427 from @chqrlie for further details.



      The code can also be changed like:



      int cmpfunc (const void * a, const void * b){
      Individual* pA = a;
      Individual* pB = b;
      double fitnessA = pA->fitness;
      double fitnessB = pB->fitness;
      if (fitnessA > fitnessB) return 1;
      if (fitnessA < fitnessB) return -1;
      return 0;
      }





      share|improve this answer






























        5














        This part



        *(Individual*)a->fitness


        is wrong. You try to access fitness using -> but at the same time you dereference the pointer using *. You can't do both!



        Here are two solutions.



        Solution A: Dereference using * and access fitness using .



        (*(Individual*)a).fitness


        Solution B: Access fitness using ->



        ((Individual*)a)->fitness


        Both solutions also requires a cast from void* to Individual*.



        The same apply for variable b



        If you are a beginner in C I'll recommend that you avoid using compact statements where multiple things happens. Instead split the compact statement into a number of individual statements. That will make the code easier to understand and debug. Like:



        int cmpfunc (const void * a, const void * b){
        Individual* pA = a;
        Individual* pB = b;
        double fitnessA = pA->fitness;
        double fitnessB = pB->fitness;
        return fitnessA - fitnessB;
        }


        You don't need to worry about performance. The compiler will optimize the code to be just as efficient as the single statement code.



        That said - as spotted by @chqrlie - notice that the compare code is wrong!



        The function returns an integer but fitnessA - fitnessB is a double that will be converted to an integer. So 0.1 - 0.0 will end up returning 0 - which is not what you want.



        You can see this answer https://stackoverflow.com/a/53466034/4386427 from @chqrlie for further details.



        The code can also be changed like:



        int cmpfunc (const void * a, const void * b){
        Individual* pA = a;
        Individual* pB = b;
        double fitnessA = pA->fitness;
        double fitnessB = pB->fitness;
        if (fitnessA > fitnessB) return 1;
        if (fitnessA < fitnessB) return -1;
        return 0;
        }





        share|improve this answer




























          5












          5








          5







          This part



          *(Individual*)a->fitness


          is wrong. You try to access fitness using -> but at the same time you dereference the pointer using *. You can't do both!



          Here are two solutions.



          Solution A: Dereference using * and access fitness using .



          (*(Individual*)a).fitness


          Solution B: Access fitness using ->



          ((Individual*)a)->fitness


          Both solutions also requires a cast from void* to Individual*.



          The same apply for variable b



          If you are a beginner in C I'll recommend that you avoid using compact statements where multiple things happens. Instead split the compact statement into a number of individual statements. That will make the code easier to understand and debug. Like:



          int cmpfunc (const void * a, const void * b){
          Individual* pA = a;
          Individual* pB = b;
          double fitnessA = pA->fitness;
          double fitnessB = pB->fitness;
          return fitnessA - fitnessB;
          }


          You don't need to worry about performance. The compiler will optimize the code to be just as efficient as the single statement code.



          That said - as spotted by @chqrlie - notice that the compare code is wrong!



          The function returns an integer but fitnessA - fitnessB is a double that will be converted to an integer. So 0.1 - 0.0 will end up returning 0 - which is not what you want.



          You can see this answer https://stackoverflow.com/a/53466034/4386427 from @chqrlie for further details.



          The code can also be changed like:



          int cmpfunc (const void * a, const void * b){
          Individual* pA = a;
          Individual* pB = b;
          double fitnessA = pA->fitness;
          double fitnessB = pB->fitness;
          if (fitnessA > fitnessB) return 1;
          if (fitnessA < fitnessB) return -1;
          return 0;
          }





          share|improve this answer















          This part



          *(Individual*)a->fitness


          is wrong. You try to access fitness using -> but at the same time you dereference the pointer using *. You can't do both!



          Here are two solutions.



          Solution A: Dereference using * and access fitness using .



          (*(Individual*)a).fitness


          Solution B: Access fitness using ->



          ((Individual*)a)->fitness


          Both solutions also requires a cast from void* to Individual*.



          The same apply for variable b



          If you are a beginner in C I'll recommend that you avoid using compact statements where multiple things happens. Instead split the compact statement into a number of individual statements. That will make the code easier to understand and debug. Like:



          int cmpfunc (const void * a, const void * b){
          Individual* pA = a;
          Individual* pB = b;
          double fitnessA = pA->fitness;
          double fitnessB = pB->fitness;
          return fitnessA - fitnessB;
          }


          You don't need to worry about performance. The compiler will optimize the code to be just as efficient as the single statement code.



          That said - as spotted by @chqrlie - notice that the compare code is wrong!



          The function returns an integer but fitnessA - fitnessB is a double that will be converted to an integer. So 0.1 - 0.0 will end up returning 0 - which is not what you want.



          You can see this answer https://stackoverflow.com/a/53466034/4386427 from @chqrlie for further details.



          The code can also be changed like:



          int cmpfunc (const void * a, const void * b){
          Individual* pA = a;
          Individual* pB = b;
          double fitnessA = pA->fitness;
          double fitnessB = pB->fitness;
          if (fitnessA > fitnessB) return 1;
          if (fitnessA < fitnessB) return -1;
          return 0;
          }






          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Nov 25 '18 at 11:18

























          answered Nov 25 '18 at 7:05









          43864274386427

          21.6k31846




          21.6k31846

























              2














              Assuming you call qsort with an array of Individual structures, you should cast the arguments received by the compare function as pointers to Individual structures, preferably const Individual * to avoid warnings.



              You can then compare the fitness members and return an ordering value. Note that you cannot just return the difference of the values as these may be non integral and the difference may even overflow the range of type int.



              Here is a classic way to do this:



              int cmpfunc(const void *a, const void *b) {
              const Individual *aa = a;
              const Individual *bb = b;
              /* return -1, 0 or 1 depending on the comparison results */
              return (aa->fitness > bb->fitness) - (aa->fitness < bb->fitness);
              }





              share|improve this answer






























                2














                Assuming you call qsort with an array of Individual structures, you should cast the arguments received by the compare function as pointers to Individual structures, preferably const Individual * to avoid warnings.



                You can then compare the fitness members and return an ordering value. Note that you cannot just return the difference of the values as these may be non integral and the difference may even overflow the range of type int.



                Here is a classic way to do this:



                int cmpfunc(const void *a, const void *b) {
                const Individual *aa = a;
                const Individual *bb = b;
                /* return -1, 0 or 1 depending on the comparison results */
                return (aa->fitness > bb->fitness) - (aa->fitness < bb->fitness);
                }





                share|improve this answer




























                  2












                  2








                  2







                  Assuming you call qsort with an array of Individual structures, you should cast the arguments received by the compare function as pointers to Individual structures, preferably const Individual * to avoid warnings.



                  You can then compare the fitness members and return an ordering value. Note that you cannot just return the difference of the values as these may be non integral and the difference may even overflow the range of type int.



                  Here is a classic way to do this:



                  int cmpfunc(const void *a, const void *b) {
                  const Individual *aa = a;
                  const Individual *bb = b;
                  /* return -1, 0 or 1 depending on the comparison results */
                  return (aa->fitness > bb->fitness) - (aa->fitness < bb->fitness);
                  }





                  share|improve this answer















                  Assuming you call qsort with an array of Individual structures, you should cast the arguments received by the compare function as pointers to Individual structures, preferably const Individual * to avoid warnings.



                  You can then compare the fitness members and return an ordering value. Note that you cannot just return the difference of the values as these may be non integral and the difference may even overflow the range of type int.



                  Here is a classic way to do this:



                  int cmpfunc(const void *a, const void *b) {
                  const Individual *aa = a;
                  const Individual *bb = b;
                  /* return -1, 0 or 1 depending on the comparison results */
                  return (aa->fitness > bb->fitness) - (aa->fitness < bb->fitness);
                  }






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Nov 25 '18 at 11:12

























                  answered Nov 25 '18 at 9:01









                  chqrliechqrlie

                  61.2k747104




                  61.2k747104






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53465147%2fwriting-a-compare-function-for-a-structure-for-qsort%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Costa Masnaga

                      Fotorealismo

                      Sidney Franklin