Reputation: 305
I have an array of floats where I want to do some swapping. So, I looked around on the net and I found out that the most efficient way of doing it is through XOR swapping XOR swap algorithm
So I have this code snippet:
float tmp;
tmp = x[i];
x[i] = x[j];
x[j] = tmp;
And I've tried to change it to the XOR swap way:
/*Made sure that address x[i] is different than the one of x[j] */
float* a= &x[i];
float* b= &x[j];
a ^= b;
b ^= a;
a ^= b;
But I get this : error: invalid operands to binary ^ (have ‘float *’ and ‘float *’)
.
Honestly, I'm not such an expert with pointers and sometimes it confuses me, So, can someone tell me what I'm doing wrong.
Upvotes: 1
Views: 578
Reputation: 2138
You want to swap the address and not the actual value if you do a ^= b
with pointers. Instead you should use the values. The next problem is that you want to XOR floats and that is not possible. Instead you could take the single bytes of your float and XOR them:
void swap( float * one, float * two){
unsigned char* a= (unsigned char *)one;
unsigned char* b= (unsigned char *)two;
for(int i = 0; i < sizeof(float); i++){
*a ^= *b;
*b ^= *a;
*a ^= *b;
a++;
b++;
}
}
int main(void) {
float one = 1.0, two = 2.0;
swap(&one, &two);
printf("%f %f", one, two); // prints 2.0000 1.0000
return 0;
}
This is much additional work, not worth the effort and pretty sure slower. You can use XOR swapping for integer and regular swapping with a temp variable for floats.
Upvotes: 2
Reputation: 17041
The short answer: You cannot perform bitwise operations on pointers. Unfortunately, you cannot perform bitwise operations on floats, either! Don't use the XOR swap for float
values.
The commenters gave you the short answer. Now for my take on the long answer —
Bitwise operations such as ^
are defined for integers. However, a pointer is not necessarily an integer. On real-mode x86, a pointer includes, or is in some way related to, two integers: a segment and an offset (additional info).
Worse, those two integers overlap, so changes to one also change the other. Therefore, there is no single, unambiguous way to define ^
or other bitwise operations for pointers.
Lots of code does assume that pointers can be treated as integers, since segmented addressing is less common than it used to be. However, the C standard still has to support less-common architectures, so does not define bitwise operations on pointers.
I see that the example you linked uses pointers. That is because, in C, you have to use pointers to pass values back to the caller of a function through parameters. The code you linked is:
void xorSwap (int *x, int *y) {
if (x != y) {
*x ^= *y;
*y ^= *x;
*x ^= *y;
}
}
(enwiki, CC-BY-SA 3.0). You could call that in your context as
if(x[i]!=x[j]) xorSwap(&x[i], &x[j]);
if x
were an array of int
s, and it would swap the contents of the array elements, as I think you expect. When you are using XOR swap directly, rather than via a function, you do not need to use pointers at all. For example:
if(x[i]!=x[j]) {
x[i] ^= x[j];
x[j] ^= x[i];
x[i] ^= x[j];
}
should work, again, provided that x
is int
and not float
.
Upvotes: 2
Reputation: 253
It is normal.
float* a= x[i];
is invalid. Your array of float is x. You are trying to get a value from the array. So it should be :
float a = x[i];
float b = x[j];
If you put an '*', you make a pointer. Anyway, as Wikipedia shows, it should not work. Only on integers.
Upvotes: -1