Writing a compare function for a structure for qsort?
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
add a comment |
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
@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
add a comment |
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
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
c genetic-algorithm qsort
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
add a comment |
@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
add a comment |
2 Answers
2
active
oldest
votes
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;
}
add a comment |
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);
}
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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;
}
add a comment |
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;
}
add a comment |
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;
}
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;
}
edited Nov 25 '18 at 11:18
answered Nov 25 '18 at 7:05
43864274386427
21.6k31846
21.6k31846
add a comment |
add a comment |
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);
}
add a comment |
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);
}
add a comment |
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);
}
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);
}
edited Nov 25 '18 at 11:12
answered Nov 25 '18 at 9:01
chqrliechqrlie
61.2k747104
61.2k747104
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
@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