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, Times开发者_运维问答tampLo) unsigned long
s. 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
- guaranteed to be at least 64 bits, and
- easy to print with
printf
- you don't need the PRIu64 macro, and - 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.
精彩评论