【问题标题】:How to combine 4 uint32_t ints into a whole 128 bit int and return如何将 4 个 uint32_t int 组合成一个完整的 128 位 int 并返回
【发布时间】:2016-06-02 07:08:42
【问题描述】:

作为头文件中结构(我们称之为 ASM)的一部分,声明了四个 uint32_t int。

uint32_t Result1; 
uint32_t Result2; 
uint32_t Result3; 
uint32_t Result4; 

我想像这样访问这些:ASM->Result1, ASM->Result2 等并将它们组合成一个 128 位 int,其中 Result1 是左侧的 0-31 位,所以最后我会有:

return 128bitint = Result1Result2Result3Result4;

如何做到这一点?

【问题讨论】:

  • 应该用什么数据类型保存它们?
  • 我认为即使 unsigned long long 也只有 64 位...也许您可以考虑使用 char 数组来保存这些结果:char a[16];
  • 有一个 GCC 扩展,它定义了 __int128,一个 128 位整数类型,也可以是无符号的。但是,我不知道它的便携性或 OP 是否可以访问 GCC。

标签: c integer bit 128-bit


【解决方案1】:

我会使用联合:

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

int main(void) {
    union {
        struct {
            uint32_t v1;
            uint32_t v2;
            uint32_t v3;
            uint32_t v4;
        } __attribute__((packed));
        unsigned __int128 i128;
    } t128;
    t128.v1 = 0x22221111;
    t128.v2 = 0x44443333;
    t128.v3 = 0x66665555;
    t128.v4 = 0x88887777;

    printf("0x%016"PRIx64"%016"PRIx64"\n", (uint64_t)(t128.i128 >> 64), (uint64_t)t128.i128);

    return 0;
}

这给出了:

0x88887777666655554444333322221111

作为英特尔(小端)架构的结果。

【讨论】:

  • @chqrlie:当然,你是对的。已修复,谢谢。
  • 抱歉,我不够精确,%lx 不一定处理 64 位(即使在 64 位代码中,Windows 上的 long 也是 32 位)。您必须使用PRIx64 宏或使用llx 并将参数转换为(unsigned long long)printf("0x%016"PRIx64"%016"PRIx64"\n", (uint64_t)(t128.i128 &gt;&gt; 64), (uint64_t)t128.i128);printf("0x%016llx%016llx\n", (unsigned long long)(uint64_t)(t128.i128 &gt;&gt; 64), (unsigned long long)(uint64_t)t128.i128);
  • @chqrlie:哦,我不知道 PRIx64 宏。多么有用!再次感谢您。
  • 我 +1 是因为你提到了字节顺序...我可能只是返回结构以获得最大的可移植性,即,不要担心联合
  • 遗憾的是联合技巧是 UB,并且您假设没有结构包装。一个 32 位无符号数组和一个 memcpy 是可行的。
【解决方案2】:

为此,您需要支持 128 位整数。

在适当的平台上使用gcc,您可以这样写:

__uint128_t getval(const struct ASM *s) {
    return ((__uint128_t)s->Result1 <<  0) |
           ((__uint128_t)s->Result2 << 32) |
           ((__uint128_t)s->Result3 << 64) |
           ((__uint128_t)s->Result4 << 96);
}

请注意,Result1 是左侧的第 0-31 位,您的意思并不清楚。为了澄清您的规范,您必须确定 Result1 是低位 32 位(英特尔架构,小端,我上面的代码),还是高位 32 位(大端架构)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-14
    • 1970-01-01
    • 1970-01-01
    • 2020-10-31
    • 1970-01-01
    • 2022-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多