简体   繁体   English

如何在C中使用两个32位整数作为64位?

[英]How do I use two 32-bit integers as a 64-bit in C?

I am using a library that returns a structure with a time stamp that is represented by two (TimestampHi, TimestampLo) unsigned long s. 我正在使用一个返回带有时间戳的结构的库,该时间戳由两个(TimestampHi,TimestampLo) unsigned long s表示。 I pretty much only need the timestamp printed out as %llu in printf. 我几乎只需要在printf中将时间戳打印为%llu

What's the easiest way to get the data from these two ints and correctly use it as a uint64_t? 从这两个int中获取数据并将其正确用作uint64_t的最简单方法是什么?

Assuming that unsigned long long is a 64-bit type on your platform 假设unsigned long long在您的平台上是64位类型

assert(sizeof(unsigned long) * CHAR_BIT == 32);
assert(sizeof(unsigned long long) * CHAR_BIT == 64);
// Static asserts are more appropriate in cases like this

unsigned long long Timestamp = TimestampHi;
Timestamp <<= 32; Timestamp += TimestampLo; 

And then print the Timestamp value. 然后打印Timestamp值。

Same thing as an one-liner 与单线一样

unsigned long long Timestamp = ((unsigned long long) TimestampHi << 32) + TimestampLo; 

or simply 或简单地

printf("%llu\n", ((unsigned long long) TimestampHi << 32) + TimestampLo);

If you wish to abstract your code from bit-based operations, the expression can be rewritten as 如果您希望从基于位的操作中提取代码,则可以将该表达式重写为

TimestampHi * ((unsigned long long) ULONG_MAX + 1) + TimestampLo
unsigned long long t = (unsigned long long)hi << 32 | lo;
printf("%ull\n", t);

Note that I'm using unsigned long long instead of uint64_t because it's 请注意,我使用的是unsigned long long而不是uint64_t因为它是

  1. guaranteed to be at least 64 bits, and 保证至少为64位,并且
  2. easy to print with printf - you don't need the PRIu64 macro, and 使用printf易于打印-您不需要PRIu64宏,并且
  3. you mentioned %ull in the question. 您在问题中提到了%ull

However, if you want to support MSVC (which is nowhere near conformant to modern standards), you might be better off with: 但是,如果您想支持MSVC(远远不符合现代标准),则最好采用以下方法:

uint64_t t = (uint64_t)hi << 32 | lo;
printf("%" PRIu64 "\n", t);

This way you can ensure (via replacements for the missing system headers) that uint64_t is properly defined as MSVC's 64-bit unsigned type, and PRIu64 is defined as the proper printf format specifier to print it. 这样,您可以确保(通过替换缺少的系统标头)将uint64_t正确定义为MSVC的64位无符号类型,并将PRIu64定义为正确的printf格式说明符以进行打印。

Andrey answered what you do if you have some 64-bit type, but maybe you have only 32-bit types. 如果您有一些 64位类型,Andrey回答了您要做什么,但是也许只有32位类型。 In that case, what you need is a multi-precision integer library. 在这种情况下,您需要的是一个多精度整数库。 The GNU MP library is excellent, but may be overkill for your purposes. GNU MP库非常出色,但是对于您的目的而言可能会显得有些过时。 I8lib implements "double" precision integer arithmetic (ie no more than 64 bits) and might do you fine, but i've never used it. I8lib实现“双精度”精度整数算术(即不超过64位),可能还不错,但我从未使用过。

If the answer will be less than 2^49, and 64-bit ints aren't available, how about printf("%1.0f",4294967296.0*upper_part + lower_part)? 如果答案小于2 ^ 49,并且没有64位整数,则printf(“%1.0f”,4294967296.0 * upper_part + lower_part)怎么样? That wouldn't work on platforms where a double is less than 64 bits, but it would work on many platforms without 64-bit ints. 这在double小于64位的平台上不起作用,但是在没有64位int的许多平台上都可以工作。

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

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