Reputation: 4454
I made my bubble sort program generic. I went on testing it and it was working well until I placed a negative number in the array, and I was surprised that it was pushed to the end, making it bigger than positive numbers.
Obviously memcmp
is the reason, so why does memcmp()
regard negative numbers greater than positive numbers?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void bubblesortA(void *_Buf, size_t bufSize, size_t bytes);
int main(void)
{
size_t n, bufsize = 5;
int buf[5] = { 5, 1, 2, -1, 10 };
bubblesortA(buf, 5, sizeof(int));
for (n = 0; n < bufsize; n++)
{
printf("%d ", buf[n]);
}
putchar('\n');
char str[] = "bzqacd";
size_t len = strlen(str);
bubblesortA(str, len, sizeof(char));
for (n = 0; n < len; n++)
{
printf("%c ", str[n]);
}
putchar('\n');
return 0;
}
void bubblesortA(void *buf, size_t bufSize, size_t bytes)
{
size_t x, y;
char *ptr = (char*)buf;
void *tmp = malloc(bytes);
for (x = 0; x < bufSize; x++)
{
ptr = (char *)buf;
for (y = 0; y < (bufSize - x - 1); y++)
{
if (memcmp(ptr, ptr + bytes, bytes) > 0)
{
memcpy(tmp, ptr, bytes);
memcpy(ptr, ptr + bytes, bytes);
memcpy(ptr + bytes, tmp, bytes);
}
ptr += bytes;
}
}
free(tmp);
}
Edit:
So, How do I modify the program to make it compare correctly?
Upvotes: 3
Views: 3394
Reputation: 154070
Answering OP's appended edit
How can i modify the program to make it compare correctly?
To compare two types as an anonymous bit pattern, memcmp()
works fine. To compare two values of some type, code needs a compare function for that type. Following qsort()
style:
void bubblesortA2(void *_Buf,size_t bufSize,size_t bytes,
int (*compar)(const void *, const void *)))
{
....
// if(memcmp(ptr,ptr+bytes,bytes) > 0)
if((*compar)(ptr,ptr+bytes) > 0)
....
To compare int
, pass in a compare int
function. Notice that a
, b
are the addresses to the objects.
int compar_int(const void *a, const void *b) {
const int *ai = (const int *)a;
const int *bi = (const int *)b;
return (*ai > *bi) - (*ai < *bi);
}
To compare char
, pass in a compare char
function
int compar_int(const void *a, const void *b) {
const char *ac = (const char *)a;
const char *bc = (const char *)b;
return (*ac > *bc) - (*ac < *bc);
}
Upvotes: 5
Reputation: 7352
In the notation that numbers and negative numbers are counted, the first bit is used as signbit, a bit that indicates wether a number is negative or positive.
It becomes clear if we look at the binary representations of 2 numbers. Its worth noting that memcmp
just compares 2 numbers as if they were both unsigned numbers of the lenght specified.
-27 in binary notation (8 bit notation, twos complement): 1110 0101
+56 in binary notation : 0011 1000
If you compare the two as if they were positive, you'll note that the -27 representation is actually bigger.
Upvotes: 0
Reputation: 311048
Negative numbers have sign bit (the most significant bit) set to 1. Function memcmp
compares bytes as unsigned values. So it considers the sign bit as a value bit. As result sometimes negative numbers are greater than positive numbers.
Upvotes: 0
Reputation: 12047
memcmp
compares bytes, it does not know if the bytes represent int
s, double
s, strings, ...
So it can not do any better that treat the bytes as unsigned numbers. Because a negative integer is normally represented using two's-complement, the highest bit of a negative integer is set, making it bigger than any positive signed integer.
Upvotes: 7