64位值的反转字节

时间:2014-02-02 06:13:24

标签: c byte reverse swap endianness

我试图反转分配的64位地址指针的字节并使用以下代码:

char swapPtr(char x){
x = (x & 0x00000000FFFFFFFF) << 32 | (x & 0xFFFFFFFF00000000) >> 32;
x = (x & 0x0000FFFF0000FFFF) << 16 | (x & 0xFFFF0000FFFF0000) >> 16;
x = (x & 0x00FF00FF00FF00FF) << 8  | (x & 0xFF00FF00FF00FF00) >> 8;
return x;
}

但是,它只会让一切变得混乱。但是,类似的功能适用于64位长。是否需要为指针做些不同的事情?

我进行函数调用的方式是一个问题吗?

指针:

*(char*)loc = swapPtr(*(char*)loc);

很长一段时间:

*loc = swapLong(*loc);

3 个答案:

答案 0 :(得分:7)

您无法使用char x作为指针!!!! char只有一个字节长。

至少需要

unsigned long int swapPtr(unsigned long int x) {

或者更好,使用指针的类型

void* swapPtr(void* x) {

当您开始移位指针时,您的编译器很可能会抱怨;在这种情况下,最好将显式转换为无符号的64位整数:

#include <stdint.h>
uint64_t x;

另请注意,您必须使用变量的地址进行调用,因此您可以使用

进行调用
result = swapLong(&loc);

不是*loc(查看loc指向的位置 - 值,而不是地址)。

完成计划:

#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));
}

输出:

the address of a is 0x00007fff6b133b1b
swapping all the bytes gives 0x1b3b136bff7f0000

编辑您可以使用类似

的内容
#include <inttypes.h>

printf("the address of a is 0x%016" PRIx64 "\n", (uint64_t)(&a));

其中宏PRIx64扩展为“您需要以十六进制格式打印64位数字的格式字符串”。它比上面的要清洁一点。

答案 1 :(得分:3)

以下是将64位值从LE转换为BE的替代方法,反之亦然。

您可以通过定义var_type基本上将此方法应用于任何类型:

typedef long long var_type;

通过指针反转:

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;
    }
}

按值反转:

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;
}

答案 2 :(得分:2)

您还可以使用 _bswap64 内在函数(在Skylake Architecture上,它的延迟为2,吞吐量为0.5)。它是汇编指令function coins(coin) { coin.setBounce(1); coin.body.setGravityY(300); this.physics.add.collider(coin, platforms); this.physics.add.collider(player, coin, collectCoin, null, this); coin.setVelocityX(60); coin.setVelocityY(-300); coin.setCollideWorldBounds(true); }的包装,因此可能是最有效的:

反转64位整数a的字节顺序,并将结果存储在dst中。提供此内在函数可在小端值和大端值之间进行转换。

bswap r64

NB:别忘了标题