开发者

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

开发者 https://www.devze.com 2023-01-11 18:17 出处:网络
I am using a library that returns a structure with a time stamp that is represented by two (TimestampHi, Times开发者_运维问答tampLo) unsigned longs. I pretty much only need the timestamp printed out a

I am using a library that returns a structure with a time stamp that is represented by two (TimestampHi, Times开发者_运维问答tampLo) unsigned longs. I pretty much only need the timestamp printed out as %llu in printf.

What's the easiest way to get the data from these two ints and correctly use it as a uint64_t?


Assuming that unsigned long long is a 64-bit type on your platform

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.

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

  1. guaranteed to be at least 64 bits, and
  2. easy to print with printf - you don't need the PRIu64 macro, and
  3. you mentioned %ull in the question.

However, if you want to support MSVC (which is nowhere near conformant to modern standards), you might be better off with:

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.


Andrey answered what you do if you have some 64-bit type, but maybe you have only 32-bit types. 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. I8lib implements "double" precision integer arithmetic (i.e. no more than 64 bits) and might do you fine, but i've never used it.


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)? 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消