繁体   English   中英

如何在32位架构中为64位分配64位无符号long long

[英]how to assign 64 bit unsigned long long to 32 bit structure in 32 bit architecture

我有2个核心,一个是32位,另一个是64位。

在64位计算机上,我支持unsigned long long,我需要将此值分配给将在32位计算机上访问的变量,例如:

typedef struct {
    unsigned int low;
    unsigned int high;
} myint64_t;

myint64_t app_sc;

以下是64位计算机的代码段:

unsigned long long sc;

/* Calculate sc */
...

现在在64位计算机上,我需要为app_sc分配“ sc”,并将其用于64位计算机上的某些计算。

我正在尝试做这样的事情:

app_sc = sc;

但是编译器给我编译时错误。 我可以类似地做:

 app_sc.low = sc & 0xFFFFFFFF;
 app_sc.high = (sc>>32) & (0xFFFFFFFF);

但这是否可以保证在所有情况下都有效?

有什么更好的方法吗?

在不太老的编译器支持相当新的C标准(可能是C99,甚至更早)的情况下,您应该有一个<stdint.h>标头,为您提供类似int64_t (用于带符号的64位整数)或uint64_t (用于无符号)的类型。 64位整数),即使在32位计算机上,也正是64位。

如果您的编译器没有,我强烈建议升级您的编译器。 您可能会使用GCC (除非您的目标架构非常奇怪,不受GCC支持)。 最新的GCC版本是4.7。

请注意,实际上在32位计算机上需要64位算术运算才能有效地支持一些编译器。 (例如,使用带有进位说明的加法)。 即使需要库来提供最复杂的操作(例如32位计算机上的64位除法),也不能仅通过库来完成。 换句话说,对于32位机器,不能在C中移植快速64位算术。

对于更大的数字,请考虑使用任意精度的数字(称为bigints ),例如通过GNU gmp库。 这样的库使用非平凡的算法(因此,即使数学很困难,您也可以阅读其中的整本书,并通过发明有竞争力的bigint实现方案来获得博士学位)。

首先,我同意在可能的情况下使用stdint类型的建议,因此我自己会这样做。

其次,我想到的唯一可能便宜的转换方式是通过工会,例如

union Int64
{
    uint64_t val64;
    struct {
        uint32_t lo32;
        uint32_t hi32;
    };
};

union Int64 i64;
i64.val64 = sc;
app_sc.low = i64.lo32;
app_sc.high = i64.hi32;

注意事项

  • 如果这样做需要存储和重新加载(如图所示),则它可能比按位操作要昂贵得多
    • 如果您可以将现有的app_sc转换为该联合的实例(跳过32位加载),则可能值得
  • 或者,如果sc已经真正存储在内存中的某个位置,则可以将其地址(union Int64 *)(union Int64 *)
    • 当然,如果sc当前被分配了一个寄存器并且脏了,那么使用该地址可能仍然会强制存储
  • 原则上,现在或以后的ABI可能存在包装和对齐问题
  • 这是与架构有关的,因此后续的端口可能意味着更改联合(我假设上面的x86 little-endianness)

坦白地说,它很脆弱,正如我希望警告所示。 不过,这是另一种方式,您可以决定是否对您的情况也更好

即使在32位计算机上,您的编译器也可能支持“ long long int”。 试试吧?

您可以使用头文件stdint.h来使用带符号/无符号变量uint64_t / int64_t / ... uint8_t / int8_t以获得更好的解释: http ://pubs.opengroup.org/onlinepubs/007904975/basedefs/stdint.h.html

通过32位和64位体系结构,改变的是指针的大小,因此unsigned long long将在32位环境中以与在64位环境中相同的方式工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM