我有2个内核,一个是32位,另一个是64位。
在64位机器上,我支持unsigned long long,我需要将这个值赋给一个可以在32位机器上访问的varriable,例如: -
typedef struct {
unsigned int low;
unsigned int high;
} myint64_t;
myint64_t app_sc;
以下是64位计算机的代码段:
unsigned long long sc;
/* Calculate sc */
...
现在在64位机器上,我需要分配" sc"到app_sc,并将其用于64位机器上的某些计算。
我试图做这样的事情: -
app_sc = sc;
但编译器给出了编译时错误。 我可以这样做,类似这样: -
app_sc.low = sc & 0xFFFFFFFF;
app_sc.high = (sc>>32) & (0xFFFFFFFF);
但是这可以保证,它会适用于所有情况吗?
有没有更好的方法呢?
答案 0 :(得分:5)
使用一个不太旧的编译器支持一个合理的最新C标准(可能是C99,甚至可能更早),你应该有一个<stdint.h>
标题给你一个类似int64_t
的类型(对于一个有符号的64位整数)或uint64_t
(对于无符号的64位整数),正好是64位,即使在32位机器上也是如此。
如果你的编译器没有它,我强烈建议升级你的编译器。您可以使用GCC(除非您有一个非常奇怪的目标架构,GCC不支持)。最新的GCC版本是4.7。
请注意,32位机器上的64位算术实际上需要一些编译器支持才能合理有效。 (例如,使用附带携带说明)。它不能仅通过库来完成,即使需要库来提供最复杂的操作(例如32位机器上的64位分区)。换句话说,对于32位机器,快速64位算术不能在C中进行可移植编码。
对于更大的数字,请考虑使用任意精度数字(称为 bigints),例如通过GNU gmp库。这些库使用非平凡的算法(所以即使数学也很困难,你可以通过发明有竞争力的bigint实现来阅读整本书并获得博士学位。)
答案 1 :(得分:3)
首先,我同意尽可能使用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 *)
sc
目前已经分配了一个寄存器并且很脏,那么取走地址可能会强行存储坦率地说,这很脆弱,我希望这些警告显示出来。不过,这是另一种方式,你可以决定它是否也更好。
答案 2 :(得分:1)
您的编译器,即使在32位机器上,也可能支持“long long int”。试试吧?
答案 3 :(得分:1)
您可以使用头文件stdint.h来使用有符号/无符号变量uint64_t / int64_t / ... uint8_t / int8_t 为了更好的解释:http://pubs.opengroup.org/onlinepubs/007904975/basedefs/stdint.h.html
答案 4 :(得分:0)
通过32位和64位架构,改变的是指针的大小,因此无符号long long将在32位中以与64位相同的方式工作。