Как использовать два 32-разрядных целых числа в качестве 64-разрядного в C? - PullRequest
1 голос
/ 14 августа 2010

Я использую библиотеку, которая возвращает структуру с меткой времени, которая представлена ​​двумя (TimestampHi, TimestampLo) unsigned long s.Мне в основном нужна только временная метка, напечатанная как %llu в printf.

Какой самый простой способ получить данные из этих двух целых и правильно использовать их как uint64_t?

Ответы [ 4 ]

10 голосов
/ 14 августа 2010

Предполагая, что 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; 

, а затем выведите значение Timestamp.

То же самое, что и в одной строке

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

или просто

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

Если вы хотите абстрагировать свой код от битовых операций, выражение можно переписать как

TimestampHi * ((unsigned long long) ULONG_MAX + 1) + TimestampLo
4 голосов
/ 14 августа 2010
unsigned long long t = (unsigned long long)hi << 32 | lo;
printf("%ull\n", t);

Обратите внимание, что я использую unsigned long long вместо uint64_t, потому что это

  1. гарантированно должно быть не менее 64 бит, а
  2. легко печатать с printf - вам не нужен макрос PRIu64, а
  3. Вы упомянули %ull в вопросе.

Однако, если вы хотите поддерживать MSVC (который далеко не соответствует современным стандартам), вам может быть лучше:

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

Таким образом, вы можете обеспечить (посредством замены отсутствующих системных заголовков), что uint64_t правильно определен как 64-битный тип беззнакового MSVC, а PRIu64 определен как правильный спецификатор формата printf для его печати.

1 голос
/ 14 августа 2010

Андрей ответил, что вы делаете, если у вас есть какой-то 64-битный тип, но, возможно, у вас есть только 32-битные типы.В этом случае вам нужна целочисленная библиотека с множественной точностью.Библиотека GNU MP превосходна, но может быть излишней для ваших целей. I8lib реализует целочисленную арифметику "двойной" точности (т.е. не более 64 бит) и может подойти, но я никогда не использовал ее.

0 голосов
/ 14 августа 2010

Если ответ будет меньше 2 ^ 49, а 64-разрядные числа недоступны, как насчет printf ("% 1.0f", 4294967296.0 * upper_part + lower_part)? Это не сработает на платформах, где double меньше 64 бит, но на многих платформах без 64-битных целых.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...