簡體   English   中英

如何將 64 位 integer 存儲在兩個 32 位整數中並再次轉換回來

[英]How to store a 64 bit integer in two 32 bit integers and convert back again

我很確定這只是一些按位運算的問題,我只是不完全確定我應該做什么,所有搜索都返回“64 位與 32 位”。

包:

u32 x, y;
u64 v = ((u64)x) << 32 | y;

解壓:

x = (u32)((v & 0xFFFFFFFF00000000LL) >> 32);
y = (u32)(v & 0xFFFFFFFFLL);

或者,如果您對兩個32位數字的含義不感興趣:

u32 x[2];
u64 z;
memcpy(x,&z,sizeof(z));
memcpy(&z,x,sizeof(z));

使用聯合並擺脫位操作:

<stdint.h> // for int32_t, int64_t

union {
  int64_t big;
  struct {
    int32_t x;
    int32_t y;
  };
};
assert(&y == &x + sizeof(x));

就那么簡單。 big由x和y組成。

我不知道這是否比union或memcpy解決方案更好,但我不得不解壓縮/打包有符號的 64位整數並且不想掩蓋或轉移任何東西,所以我最終只是將64位值視為兩個32位值並直接分配它們,如下所示:

#include <stdio.h>
#include <stdint.h>

void repack(int64_t in)
{
    int32_t a, b;

    printf("input:    %016llx\n", (long long int) in);

    a = ((int32_t *) &in)[0];
    b = ((int32_t *) &in)[1];

    printf("unpacked: %08x %08x\n", b, a);

    ((int32_t *) &in)[0] = a;
    ((int32_t *) &in)[1] = b;

    printf("repacked: %016llx\n\n", (long long int) in);
}

基本方法如下:

uint64_t int64;
uint32_t int32_1, int32_2;

int32_1 = int64 & 0xFFFFFFFF;
int32_2 = (int64 & (0xFFFFFFFF << 32) ) >> 32;

// ...

int64 = int32_1 | (int32_2 << 32);

請注意,您的整數必須是無符號的; 或者操作未定義。

long x = 0xFEDCBA9876543210;
cout << hex << "0x" << x << endl;

int a = x ; 
cout << hex << "0x" << a << endl;
int b = (x >> 32);
cout << hex << "0x" << b << endl;

不確定這種做法是否有利於便攜性或其他,但我使用......

#include <stdio.h>
#include <stdint.h>
typedef enum {false, true} bool;
#ifndef UINT32_WIDTH
#define UINT32_WIDTH 32 // defined in stdint.h, but compiler error ??
#endif

typedef struct{
struct{                 // anonymous struct
    uint32_t    x;
    uint32_t    y;
};}ts_point;

typedef struct{
struct{                 // anonymous struct
    uint32_t    line;
    uint32_t    column;
};}ts_position;

bool    is_little_endian()
{
    uint8_t n = 1;
    return *(char *)&n == 1;
}

int main(void)
{
    uint32_t    x, y;
    uint64_t    packed;
    ts_point    *point;    // struct offers a "mask" to retreive data
    ts_position *position; // in an ordered and comprehensive way.

    x = -12;
    y = -23;
    printf("at start: x = %i | y = %i\n", x, y);
    if (is_little_endian()){
        packed = (uint64_t)y << UINT32_WIDTH | (uint64_t)x;
    }else{
        packed = (uint64_t)x << UINT32_WIDTH | (uint64_t)y;
    }
    printf("packed: position = %llu\n", packed);
    point = (ts_point*)&packed;
    printf("unpacked: x = %i | y = %i\n", point->x, point->y); // access via pointer
    position = (ts_position*)&packed;
    printf("unpacked: line = %i | column = %i\n", position->line, position->column);
    return 0;
}

我喜歡我這樣做的方式,因為它提供了很多准備,並且可以以多種方式應用,即。 02x32、04x16、08x08 等。我是 C 的新人,所以請隨時批評我的代碼和做事方式...謝謝

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM