qsort comparator function is is it really necessary to return 0?
up vote
5
down vote
favorite
I have read that the comparator function that you want to create for using qsort need to have 3 outcomes:
- a negative result if
val1 < val2
- 0 if
val1 == val2
- a positive result if
val1 > val2
As far as I know about sorting of an array based on comparison. You need to have a 'function' that compare and return true or false. For example Bubble-Sort:
int compare(int a, int b)
{
if(a>b) return 1;
return 0;
}
void bubbleSort(int arr, int n)
{
int i, j;
for (i = 0; i < n-1; i++)
for (j = 0; j < n-i-1; j++)
if ( compare(arr[j],arr[j+1]) )
swap(&arr[j], &arr[j+1]);
}
So why does the qsort comparator need to have 3 possible outcomes and not 2? Thanks.
c algorithm sorting
New contributor
MihaiM is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
add a comment |
up vote
5
down vote
favorite
I have read that the comparator function that you want to create for using qsort need to have 3 outcomes:
- a negative result if
val1 < val2
- 0 if
val1 == val2
- a positive result if
val1 > val2
As far as I know about sorting of an array based on comparison. You need to have a 'function' that compare and return true or false. For example Bubble-Sort:
int compare(int a, int b)
{
if(a>b) return 1;
return 0;
}
void bubbleSort(int arr, int n)
{
int i, j;
for (i = 0; i < n-1; i++)
for (j = 0; j < n-i-1; j++)
if ( compare(arr[j],arr[j+1]) )
swap(&arr[j], &arr[j+1]);
}
So why does the qsort comparator need to have 3 possible outcomes and not 2? Thanks.
c algorithm sorting
New contributor
MihaiM is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
IMO, this is related to the bad habit to perform binary searches as ternary searches, with early termination in case of equality. In most cases, this is counter-productive.
– Yves Daoust
6 hours ago
add a comment |
up vote
5
down vote
favorite
up vote
5
down vote
favorite
I have read that the comparator function that you want to create for using qsort need to have 3 outcomes:
- a negative result if
val1 < val2
- 0 if
val1 == val2
- a positive result if
val1 > val2
As far as I know about sorting of an array based on comparison. You need to have a 'function' that compare and return true or false. For example Bubble-Sort:
int compare(int a, int b)
{
if(a>b) return 1;
return 0;
}
void bubbleSort(int arr, int n)
{
int i, j;
for (i = 0; i < n-1; i++)
for (j = 0; j < n-i-1; j++)
if ( compare(arr[j],arr[j+1]) )
swap(&arr[j], &arr[j+1]);
}
So why does the qsort comparator need to have 3 possible outcomes and not 2? Thanks.
c algorithm sorting
New contributor
MihaiM is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
I have read that the comparator function that you want to create for using qsort need to have 3 outcomes:
- a negative result if
val1 < val2
- 0 if
val1 == val2
- a positive result if
val1 > val2
As far as I know about sorting of an array based on comparison. You need to have a 'function' that compare and return true or false. For example Bubble-Sort:
int compare(int a, int b)
{
if(a>b) return 1;
return 0;
}
void bubbleSort(int arr, int n)
{
int i, j;
for (i = 0; i < n-1; i++)
for (j = 0; j < n-i-1; j++)
if ( compare(arr[j],arr[j+1]) )
swap(&arr[j], &arr[j+1]);
}
So why does the qsort comparator need to have 3 possible outcomes and not 2? Thanks.
c algorithm sorting
c algorithm sorting
New contributor
MihaiM is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
MihaiM is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
edited 3 hours ago
uv_
453418
453418
New contributor
MihaiM is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
asked 6 hours ago
MihaiM
454
454
New contributor
MihaiM is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
New contributor
MihaiM is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
MihaiM is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
IMO, this is related to the bad habit to perform binary searches as ternary searches, with early termination in case of equality. In most cases, this is counter-productive.
– Yves Daoust
6 hours ago
add a comment |
IMO, this is related to the bad habit to perform binary searches as ternary searches, with early termination in case of equality. In most cases, this is counter-productive.
– Yves Daoust
6 hours ago
IMO, this is related to the bad habit to perform binary searches as ternary searches, with early termination in case of equality. In most cases, this is counter-productive.
– Yves Daoust
6 hours ago
IMO, this is related to the bad habit to perform binary searches as ternary searches, with early termination in case of equality. In most cases, this is counter-productive.
– Yves Daoust
6 hours ago
add a comment |
5 Answers
5
active
oldest
votes
up vote
2
down vote
accepted
Based on the comment of @Matteo Italia, there is an efficiency issue in the number of comparison and you can reduce the number of comparison using the equality as a == b and !(a < b) && !(b < a) are equivalent in some cases (for example when the values are integer).
Also, in more general case (not in qsort specifically as mentioned in comments), you need it for stability of the sort function. In equality cases, if the sort wants to be stable, it should know about the equality in the comparison. You can know more about the stabilty in sorting here.
Hence, three value return is required for stable sort methods.
It must be noted that (1)qsortis not stable and (2) it's not strictly required, but just an optimization - if you only have a "less than" operator, you can deduce the equality by using two comparisons (a == b<->!(a < b) && !(b < a)).
– Matteo Italia
6 hours ago
1
@MatteoItalia(a == b <-> !(a < b) && !(b < a))is not certainly true whena,bare floating point and a value may be not-a-number.
– chux
1 hour ago
1
qsort()is not specified to be stable.
– chux
1 hour ago
@chux NaNs with regular IEEE754<break pretty much any required property of a strict weak ordering, so, while your statement is of course technically correct, it's not really relevant to a discussion regarding sorting.
– Matteo Italia
1 hour ago
More in general, the<and==in my previous comment aren't to be intended literally as the C operators - heck they would make no sense even just for strings -, but as the comparison operators induced by a given ordering relation suitable for sorting, i.e. a strict weak ordering.
– Matteo Italia
1 hour ago
add a comment |
up vote
3
down vote
If element A == element B but the comparator function tells qsort that B > A then qsort will think there may be other elements which should be between A and B when that is not the case, and therefore perform unnecessary checks.
add a comment |
up vote
3
down vote
qsort could be written using a boolean compare function instead of a three-way compare but the specification says that it takes a three-way compare function and some (not all) implementations take advantage of the three possible cases. If your compare function doesn't conform to the specification, Undefined Behaviour will result. In this case, Undefined Behaviour might include a failure to sort correctly or a buffer overrun triggered on very rare corner cases, which you might not notice until the space shuttle is returning from orbit. So don't do that.
As to why an implementation might want the three-way comparison, here is one possibility: for inputs with a lot of repeated values, quicksort can be speeded up considerably by using a three-way partition. That can be done with a two-way comparison by doing the comparison twice in opposite directions, but an implementor, knowing that a three-way comparator is required, is likely to test for equality when that's what they want to know.
add a comment |
up vote
2
down vote
Technically, you can do with just less-than, because a == b is equivalent to !(a < b) && !(b < a).
1
Independently of Matteo's comment. ;-)
– Yves Daoust
6 hours ago
2
That is, assuming full ordering. Seems obvious as we are sorting, but it's important to remember that equivalence does not hold in the general case.
– spectras
6 hours ago
1
a == bis equivalent to !(a < b) && !(b < a)is not always true with FP math.
– chux
1 hour ago
@chux: do you have an example ?
– Yves Daoust
1 hour ago
@yves: if at least one ofaandbis NaN, all comparisons returnfalse. But!false && !falseistrue.
– rici
14 mins ago
add a comment |
up vote
1
down vote
If the quicksort inner loop is written equivalent to this:
while(x[i] < pivot) i++; // less-than
while(pivot < x[j]) j--; // less-than
then you can get away with only implementing <.
In any case, stick to the principle of least astonishment by making it more obvious what the caller is supposed to do -- if your compare function pointer is named compare and the function shouldn't behave like a usual stdlib qsort compare delegate, then it's a bad idea.
On the other hand, if your parameter is named something like less_than or isLessThan, it should be much more obvious to the caller what is expected from the comparison function:
void sort(
const void * arr,
size_t num_items,
size_t element_size,
bool (*is_less_than)(const void*, const void*)
);
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',
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
});
}
});
MihaiM is a new contributor. Be nice, and check out our Code of Conduct.
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%2f53791771%2fqsort-comparator-function-is-is-it-really-necessary-to-return-0%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
5 Answers
5
active
oldest
votes
5 Answers
5
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
Based on the comment of @Matteo Italia, there is an efficiency issue in the number of comparison and you can reduce the number of comparison using the equality as a == b and !(a < b) && !(b < a) are equivalent in some cases (for example when the values are integer).
Also, in more general case (not in qsort specifically as mentioned in comments), you need it for stability of the sort function. In equality cases, if the sort wants to be stable, it should know about the equality in the comparison. You can know more about the stabilty in sorting here.
Hence, three value return is required for stable sort methods.
It must be noted that (1)qsortis not stable and (2) it's not strictly required, but just an optimization - if you only have a "less than" operator, you can deduce the equality by using two comparisons (a == b<->!(a < b) && !(b < a)).
– Matteo Italia
6 hours ago
1
@MatteoItalia(a == b <-> !(a < b) && !(b < a))is not certainly true whena,bare floating point and a value may be not-a-number.
– chux
1 hour ago
1
qsort()is not specified to be stable.
– chux
1 hour ago
@chux NaNs with regular IEEE754<break pretty much any required property of a strict weak ordering, so, while your statement is of course technically correct, it's not really relevant to a discussion regarding sorting.
– Matteo Italia
1 hour ago
More in general, the<and==in my previous comment aren't to be intended literally as the C operators - heck they would make no sense even just for strings -, but as the comparison operators induced by a given ordering relation suitable for sorting, i.e. a strict weak ordering.
– Matteo Italia
1 hour ago
add a comment |
up vote
2
down vote
accepted
Based on the comment of @Matteo Italia, there is an efficiency issue in the number of comparison and you can reduce the number of comparison using the equality as a == b and !(a < b) && !(b < a) are equivalent in some cases (for example when the values are integer).
Also, in more general case (not in qsort specifically as mentioned in comments), you need it for stability of the sort function. In equality cases, if the sort wants to be stable, it should know about the equality in the comparison. You can know more about the stabilty in sorting here.
Hence, three value return is required for stable sort methods.
It must be noted that (1)qsortis not stable and (2) it's not strictly required, but just an optimization - if you only have a "less than" operator, you can deduce the equality by using two comparisons (a == b<->!(a < b) && !(b < a)).
– Matteo Italia
6 hours ago
1
@MatteoItalia(a == b <-> !(a < b) && !(b < a))is not certainly true whena,bare floating point and a value may be not-a-number.
– chux
1 hour ago
1
qsort()is not specified to be stable.
– chux
1 hour ago
@chux NaNs with regular IEEE754<break pretty much any required property of a strict weak ordering, so, while your statement is of course technically correct, it's not really relevant to a discussion regarding sorting.
– Matteo Italia
1 hour ago
More in general, the<and==in my previous comment aren't to be intended literally as the C operators - heck they would make no sense even just for strings -, but as the comparison operators induced by a given ordering relation suitable for sorting, i.e. a strict weak ordering.
– Matteo Italia
1 hour ago
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
Based on the comment of @Matteo Italia, there is an efficiency issue in the number of comparison and you can reduce the number of comparison using the equality as a == b and !(a < b) && !(b < a) are equivalent in some cases (for example when the values are integer).
Also, in more general case (not in qsort specifically as mentioned in comments), you need it for stability of the sort function. In equality cases, if the sort wants to be stable, it should know about the equality in the comparison. You can know more about the stabilty in sorting here.
Hence, three value return is required for stable sort methods.
Based on the comment of @Matteo Italia, there is an efficiency issue in the number of comparison and you can reduce the number of comparison using the equality as a == b and !(a < b) && !(b < a) are equivalent in some cases (for example when the values are integer).
Also, in more general case (not in qsort specifically as mentioned in comments), you need it for stability of the sort function. In equality cases, if the sort wants to be stable, it should know about the equality in the comparison. You can know more about the stabilty in sorting here.
Hence, three value return is required for stable sort methods.
edited 1 hour ago
answered 6 hours ago
OmG
7,65252643
7,65252643
It must be noted that (1)qsortis not stable and (2) it's not strictly required, but just an optimization - if you only have a "less than" operator, you can deduce the equality by using two comparisons (a == b<->!(a < b) && !(b < a)).
– Matteo Italia
6 hours ago
1
@MatteoItalia(a == b <-> !(a < b) && !(b < a))is not certainly true whena,bare floating point and a value may be not-a-number.
– chux
1 hour ago
1
qsort()is not specified to be stable.
– chux
1 hour ago
@chux NaNs with regular IEEE754<break pretty much any required property of a strict weak ordering, so, while your statement is of course technically correct, it's not really relevant to a discussion regarding sorting.
– Matteo Italia
1 hour ago
More in general, the<and==in my previous comment aren't to be intended literally as the C operators - heck they would make no sense even just for strings -, but as the comparison operators induced by a given ordering relation suitable for sorting, i.e. a strict weak ordering.
– Matteo Italia
1 hour ago
add a comment |
It must be noted that (1)qsortis not stable and (2) it's not strictly required, but just an optimization - if you only have a "less than" operator, you can deduce the equality by using two comparisons (a == b<->!(a < b) && !(b < a)).
– Matteo Italia
6 hours ago
1
@MatteoItalia(a == b <-> !(a < b) && !(b < a))is not certainly true whena,bare floating point and a value may be not-a-number.
– chux
1 hour ago
1
qsort()is not specified to be stable.
– chux
1 hour ago
@chux NaNs with regular IEEE754<break pretty much any required property of a strict weak ordering, so, while your statement is of course technically correct, it's not really relevant to a discussion regarding sorting.
– Matteo Italia
1 hour ago
More in general, the<and==in my previous comment aren't to be intended literally as the C operators - heck they would make no sense even just for strings -, but as the comparison operators induced by a given ordering relation suitable for sorting, i.e. a strict weak ordering.
– Matteo Italia
1 hour ago
It must be noted that (1)
qsort is not stable and (2) it's not strictly required, but just an optimization - if you only have a "less than" operator, you can deduce the equality by using two comparisons (a == b <-> !(a < b) && !(b < a)).– Matteo Italia
6 hours ago
It must be noted that (1)
qsort is not stable and (2) it's not strictly required, but just an optimization - if you only have a "less than" operator, you can deduce the equality by using two comparisons (a == b <-> !(a < b) && !(b < a)).– Matteo Italia
6 hours ago
1
1
@MatteoItalia
(a == b <-> !(a < b) && !(b < a)) is not certainly true when a,b are floating point and a value may be not-a-number.– chux
1 hour ago
@MatteoItalia
(a == b <-> !(a < b) && !(b < a)) is not certainly true when a,b are floating point and a value may be not-a-number.– chux
1 hour ago
1
1
qsort() is not specified to be stable.– chux
1 hour ago
qsort() is not specified to be stable.– chux
1 hour ago
@chux NaNs with regular IEEE754
< break pretty much any required property of a strict weak ordering, so, while your statement is of course technically correct, it's not really relevant to a discussion regarding sorting.– Matteo Italia
1 hour ago
@chux NaNs with regular IEEE754
< break pretty much any required property of a strict weak ordering, so, while your statement is of course technically correct, it's not really relevant to a discussion regarding sorting.– Matteo Italia
1 hour ago
More in general, the
< and == in my previous comment aren't to be intended literally as the C operators - heck they would make no sense even just for strings -, but as the comparison operators induced by a given ordering relation suitable for sorting, i.e. a strict weak ordering.– Matteo Italia
1 hour ago
More in general, the
< and == in my previous comment aren't to be intended literally as the C operators - heck they would make no sense even just for strings -, but as the comparison operators induced by a given ordering relation suitable for sorting, i.e. a strict weak ordering.– Matteo Italia
1 hour ago
add a comment |
up vote
3
down vote
If element A == element B but the comparator function tells qsort that B > A then qsort will think there may be other elements which should be between A and B when that is not the case, and therefore perform unnecessary checks.
add a comment |
up vote
3
down vote
If element A == element B but the comparator function tells qsort that B > A then qsort will think there may be other elements which should be between A and B when that is not the case, and therefore perform unnecessary checks.
add a comment |
up vote
3
down vote
up vote
3
down vote
If element A == element B but the comparator function tells qsort that B > A then qsort will think there may be other elements which should be between A and B when that is not the case, and therefore perform unnecessary checks.
If element A == element B but the comparator function tells qsort that B > A then qsort will think there may be other elements which should be between A and B when that is not the case, and therefore perform unnecessary checks.
answered 6 hours ago
Weather Vane
25.3k52038
25.3k52038
add a comment |
add a comment |
up vote
3
down vote
qsort could be written using a boolean compare function instead of a three-way compare but the specification says that it takes a three-way compare function and some (not all) implementations take advantage of the three possible cases. If your compare function doesn't conform to the specification, Undefined Behaviour will result. In this case, Undefined Behaviour might include a failure to sort correctly or a buffer overrun triggered on very rare corner cases, which you might not notice until the space shuttle is returning from orbit. So don't do that.
As to why an implementation might want the three-way comparison, here is one possibility: for inputs with a lot of repeated values, quicksort can be speeded up considerably by using a three-way partition. That can be done with a two-way comparison by doing the comparison twice in opposite directions, but an implementor, knowing that a three-way comparator is required, is likely to test for equality when that's what they want to know.
add a comment |
up vote
3
down vote
qsort could be written using a boolean compare function instead of a three-way compare but the specification says that it takes a three-way compare function and some (not all) implementations take advantage of the three possible cases. If your compare function doesn't conform to the specification, Undefined Behaviour will result. In this case, Undefined Behaviour might include a failure to sort correctly or a buffer overrun triggered on very rare corner cases, which you might not notice until the space shuttle is returning from orbit. So don't do that.
As to why an implementation might want the three-way comparison, here is one possibility: for inputs with a lot of repeated values, quicksort can be speeded up considerably by using a three-way partition. That can be done with a two-way comparison by doing the comparison twice in opposite directions, but an implementor, knowing that a three-way comparator is required, is likely to test for equality when that's what they want to know.
add a comment |
up vote
3
down vote
up vote
3
down vote
qsort could be written using a boolean compare function instead of a three-way compare but the specification says that it takes a three-way compare function and some (not all) implementations take advantage of the three possible cases. If your compare function doesn't conform to the specification, Undefined Behaviour will result. In this case, Undefined Behaviour might include a failure to sort correctly or a buffer overrun triggered on very rare corner cases, which you might not notice until the space shuttle is returning from orbit. So don't do that.
As to why an implementation might want the three-way comparison, here is one possibility: for inputs with a lot of repeated values, quicksort can be speeded up considerably by using a three-way partition. That can be done with a two-way comparison by doing the comparison twice in opposite directions, but an implementor, knowing that a three-way comparator is required, is likely to test for equality when that's what they want to know.
qsort could be written using a boolean compare function instead of a three-way compare but the specification says that it takes a three-way compare function and some (not all) implementations take advantage of the three possible cases. If your compare function doesn't conform to the specification, Undefined Behaviour will result. In this case, Undefined Behaviour might include a failure to sort correctly or a buffer overrun triggered on very rare corner cases, which you might not notice until the space shuttle is returning from orbit. So don't do that.
As to why an implementation might want the three-way comparison, here is one possibility: for inputs with a lot of repeated values, quicksort can be speeded up considerably by using a three-way partition. That can be done with a two-way comparison by doing the comparison twice in opposite directions, but an implementor, knowing that a three-way comparator is required, is likely to test for equality when that's what they want to know.
answered 2 hours ago
rici
151k19131194
151k19131194
add a comment |
add a comment |
up vote
2
down vote
Technically, you can do with just less-than, because a == b is equivalent to !(a < b) && !(b < a).
1
Independently of Matteo's comment. ;-)
– Yves Daoust
6 hours ago
2
That is, assuming full ordering. Seems obvious as we are sorting, but it's important to remember that equivalence does not hold in the general case.
– spectras
6 hours ago
1
a == bis equivalent to !(a < b) && !(b < a)is not always true with FP math.
– chux
1 hour ago
@chux: do you have an example ?
– Yves Daoust
1 hour ago
@yves: if at least one ofaandbis NaN, all comparisons returnfalse. But!false && !falseistrue.
– rici
14 mins ago
add a comment |
up vote
2
down vote
Technically, you can do with just less-than, because a == b is equivalent to !(a < b) && !(b < a).
1
Independently of Matteo's comment. ;-)
– Yves Daoust
6 hours ago
2
That is, assuming full ordering. Seems obvious as we are sorting, but it's important to remember that equivalence does not hold in the general case.
– spectras
6 hours ago
1
a == bis equivalent to !(a < b) && !(b < a)is not always true with FP math.
– chux
1 hour ago
@chux: do you have an example ?
– Yves Daoust
1 hour ago
@yves: if at least one ofaandbis NaN, all comparisons returnfalse. But!false && !falseistrue.
– rici
14 mins ago
add a comment |
up vote
2
down vote
up vote
2
down vote
Technically, you can do with just less-than, because a == b is equivalent to !(a < b) && !(b < a).
Technically, you can do with just less-than, because a == b is equivalent to !(a < b) && !(b < a).
answered 6 hours ago
Yves Daoust
36.6k72559
36.6k72559
1
Independently of Matteo's comment. ;-)
– Yves Daoust
6 hours ago
2
That is, assuming full ordering. Seems obvious as we are sorting, but it's important to remember that equivalence does not hold in the general case.
– spectras
6 hours ago
1
a == bis equivalent to !(a < b) && !(b < a)is not always true with FP math.
– chux
1 hour ago
@chux: do you have an example ?
– Yves Daoust
1 hour ago
@yves: if at least one ofaandbis NaN, all comparisons returnfalse. But!false && !falseistrue.
– rici
14 mins ago
add a comment |
1
Independently of Matteo's comment. ;-)
– Yves Daoust
6 hours ago
2
That is, assuming full ordering. Seems obvious as we are sorting, but it's important to remember that equivalence does not hold in the general case.
– spectras
6 hours ago
1
a == bis equivalent to !(a < b) && !(b < a)is not always true with FP math.
– chux
1 hour ago
@chux: do you have an example ?
– Yves Daoust
1 hour ago
@yves: if at least one ofaandbis NaN, all comparisons returnfalse. But!false && !falseistrue.
– rici
14 mins ago
1
1
Independently of Matteo's comment. ;-)
– Yves Daoust
6 hours ago
Independently of Matteo's comment. ;-)
– Yves Daoust
6 hours ago
2
2
That is, assuming full ordering. Seems obvious as we are sorting, but it's important to remember that equivalence does not hold in the general case.
– spectras
6 hours ago
That is, assuming full ordering. Seems obvious as we are sorting, but it's important to remember that equivalence does not hold in the general case.
– spectras
6 hours ago
1
1
a == b is equivalent to !(a < b) && !(b < a) is not always true with FP math.– chux
1 hour ago
a == b is equivalent to !(a < b) && !(b < a) is not always true with FP math.– chux
1 hour ago
@chux: do you have an example ?
– Yves Daoust
1 hour ago
@chux: do you have an example ?
– Yves Daoust
1 hour ago
@yves: if at least one of
a and b is NaN, all comparisons return false. But !false && !false is true.– rici
14 mins ago
@yves: if at least one of
a and b is NaN, all comparisons return false. But !false && !false is true.– rici
14 mins ago
add a comment |
up vote
1
down vote
If the quicksort inner loop is written equivalent to this:
while(x[i] < pivot) i++; // less-than
while(pivot < x[j]) j--; // less-than
then you can get away with only implementing <.
In any case, stick to the principle of least astonishment by making it more obvious what the caller is supposed to do -- if your compare function pointer is named compare and the function shouldn't behave like a usual stdlib qsort compare delegate, then it's a bad idea.
On the other hand, if your parameter is named something like less_than or isLessThan, it should be much more obvious to the caller what is expected from the comparison function:
void sort(
const void * arr,
size_t num_items,
size_t element_size,
bool (*is_less_than)(const void*, const void*)
);
add a comment |
up vote
1
down vote
If the quicksort inner loop is written equivalent to this:
while(x[i] < pivot) i++; // less-than
while(pivot < x[j]) j--; // less-than
then you can get away with only implementing <.
In any case, stick to the principle of least astonishment by making it more obvious what the caller is supposed to do -- if your compare function pointer is named compare and the function shouldn't behave like a usual stdlib qsort compare delegate, then it's a bad idea.
On the other hand, if your parameter is named something like less_than or isLessThan, it should be much more obvious to the caller what is expected from the comparison function:
void sort(
const void * arr,
size_t num_items,
size_t element_size,
bool (*is_less_than)(const void*, const void*)
);
add a comment |
up vote
1
down vote
up vote
1
down vote
If the quicksort inner loop is written equivalent to this:
while(x[i] < pivot) i++; // less-than
while(pivot < x[j]) j--; // less-than
then you can get away with only implementing <.
In any case, stick to the principle of least astonishment by making it more obvious what the caller is supposed to do -- if your compare function pointer is named compare and the function shouldn't behave like a usual stdlib qsort compare delegate, then it's a bad idea.
On the other hand, if your parameter is named something like less_than or isLessThan, it should be much more obvious to the caller what is expected from the comparison function:
void sort(
const void * arr,
size_t num_items,
size_t element_size,
bool (*is_less_than)(const void*, const void*)
);
If the quicksort inner loop is written equivalent to this:
while(x[i] < pivot) i++; // less-than
while(pivot < x[j]) j--; // less-than
then you can get away with only implementing <.
In any case, stick to the principle of least astonishment by making it more obvious what the caller is supposed to do -- if your compare function pointer is named compare and the function shouldn't behave like a usual stdlib qsort compare delegate, then it's a bad idea.
On the other hand, if your parameter is named something like less_than or isLessThan, it should be much more obvious to the caller what is expected from the comparison function:
void sort(
const void * arr,
size_t num_items,
size_t element_size,
bool (*is_less_than)(const void*, const void*)
);
answered 5 hours ago
Groo
35.1k1483158
35.1k1483158
add a comment |
add a comment |
MihaiM is a new contributor. Be nice, and check out our Code of Conduct.
MihaiM is a new contributor. Be nice, and check out our Code of Conduct.
MihaiM is a new contributor. Be nice, and check out our Code of Conduct.
MihaiM is a new contributor. Be nice, and check out our Code of Conduct.
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.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- 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%2f53791771%2fqsort-comparator-function-is-is-it-really-necessary-to-return-0%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
IMO, this is related to the bad habit to perform binary searches as ternary searches, with early termination in case of equality. In most cases, this is counter-productive.
– Yves Daoust
6 hours ago