Reverse bytes for 64-bit value
You cannot use char x
for a pointer!!!! A char
is only a single byte long.
You need at the very least
unsigned long int swapPtr(unsigned long int x) {
Or better, use the type of the pointer
void* swapPtr(void* x) {
Quite likely your compiler will complain when you start bit shifting pointers; in that case you're better off explicitly casting your argument to an unsigned 64 bit integer:
#include <stdint.h>
uint64_t x;
Note also that you have to call with the address of a variable, so you call with
result = swapLong(&loc);
not *loc
(which looks at the place where loc
is pointing - the value, not the address).
Complete program:
#include <stdio.h>
#include <stdint.h>
uint64_t swapLong(void *X) {
uint64_t x = (uint64_t) X;
x = (x & 0x00000000FFFFFFFF) << 32 | (x & 0xFFFFFFFF00000000) >> 32;
x = (x & 0x0000FFFF0000FFFF) << 16 | (x & 0xFFFF0000FFFF0000) >> 16;
x = (x & 0x00FF00FF00FF00FF) << 8 | (x & 0xFF00FF00FF00FF00) >> 8;
return x;
}
int main(void) {
char a;
printf("the address of a is 0x%016llx\n", (uint64_t)(&a));
printf("swapping all the bytes gives 0x%016llx\n",(uint64_t)swapLong(&a));
}
Output:
the address of a is 0x00007fff6b133b1b
swapping all the bytes gives 0x1b3b136bff7f0000
EDIT you could use something like
#include <inttypes.h>
printf("the address of a is 0x%016" PRIx64 "\n", (uint64_t)(&a));
where the macro PRIx64
expands into "the format string you need to print a 64 bit number in hex". It is a little cleaner than the above.
Here is an alternative way for converting a 64-bit value from LE to BE or vice-versa.
You can basically apply this method any type, by defining var_type
:
typedef long long var_type;
Reverse by pointer:
void swapPtr(var_type* x)
{
char* px = (char*)x;
for (int i=0; i<sizeof(var_type)/2; i++)
{
char temp = px[i];
px[i] = px[sizeof(var_type)-1-i];
px[sizeof(var_type)-1-i] = temp;
}
}
Reverse by value:
var_type swapVal(var_type x)
{
var_type y;
char* px = (char*)&x;
char* py = (char*)&y;
for (int i=0; i<sizeof(var_type); i++)
py[i] = px[sizeof(var_type)-1-i];
return y;
}
You may also use _bswap64 intrinsic (which has latency of 2 and a throughput of 0.5 on Skylake Architecture). It is a wrapper for the assembly instruction bswap r64
so probably the most efficient :
Reverse the byte order of 64-bit integer a, and store the result in dst. This intrinsic is provided for conversion between little and big endian values.
#include <immintrin.h>
uint64_t swapLongIntrinsic(void *X) {
return __bswap_64((uint64_t) X);
}
NB: Don't forget the header